C# ListView所有者图形和列自动调整大小
我有一个正在使用所有者图纸为一些子项绘制附加内容的项目 我发现,由于这些额外的内容占用了一些额外的空间,列表视图现在错误地计算了列“自动调整大小”的宽度,因此当有人自动调整某些列的大小时(例如,双击列调整大小手柄),列的大小会调整得太小,该列表视图中的文本在末尾以parenthases(…)呈现 是否有一种方法可以提示列表视图在自动调整大小时询问列的大小?您可以在以下两个场景中手动执行此操作:C# ListView所有者图形和列自动调整大小,c#,listview,autoresize,C#,Listview,Autoresize,我有一个正在使用所有者图纸为一些子项绘制附加内容的项目 我发现,由于这些额外的内容占用了一些额外的空间,列表视图现在错误地计算了列“自动调整大小”的宽度,因此当有人自动调整某些列的大小时(例如,双击列调整大小手柄),列的大小会调整得太小,该列表视图中的文本在末尾以parenthases(…)呈现 是否有一种方法可以提示列表视图在自动调整大小时询问列的大小?您可以在以下两个场景中手动执行此操作: 如果要修复最小宽度和最大宽度, 在列表视图的列宽更改事件中使用此选项: 如果要修复列表视图列
- 如果要修复
和最小宽度
, 在最大宽度
列表视图的
列宽更改
事件中使用此选项:
- 如果要修复
的列表视图列
,请设置 所需的列宽
在列宽度
列表视图的
列宽更改
事件中使用此选项:
没有一条消息会告诉您何时要自动调整列的大小。但正如您所提到的,用户只有两种方式可以触发该操作:双击分隔符和
Ctrl-Shift-+
。你可以截取这两个,然后做任何你喜欢的事情
步骤#1:要拦截双击,您需要将ListView
子类化,并侦听HDN\u DIVIDERDBLCLICK
通知:
protected override void WndProc(ref Message m) {
switch (m.Msg) {
case 0x4E: // WM_NOTIFY
if (!this.HandleNotify(ref m))
base.WndProc(ref m);
break;
default:
base.WndProc(ref m);
break;
}
}
protected bool HandleNotify(ref Message m) {
const int HDN_DIVIDERDBLCLICKW = (HDN_FIRST - 25);
NativeMethods.NMHEADER nmheader = (NativeMethods.NMHEADER)m.GetLParam(typeof(NativeMethods.NMHEADER));
switch (nmheader.nhdr.code) {
case HDN_DIVIDERDBLCLICKW:
if (nmheader.iItem >= 0 && nmheader.iItem < this.Columns.Count) {
this.AutoResizeColumn(nmheader.iItem);
m.Result = (IntPtr)1; // prevent the change from happening
return true;
}
break;
default:
break;
}
return false;
}
受保护的覆盖无效WndProc(参考消息m){
开关(m.Msg){
案例0x4E://WM\u NOTIFY
如果(!本手册通知(参考m))
基准WndProc(参考m);
打破
违约:
基准WndProc(参考m);
打破
}
}
受保护的bool HandleNotify(参考消息m){
const int HDN_DIVIDERDBLCLICKW=(HDN_FIRST-25);
NativeMethods.NMHEADER NMHEADER=(NativeMethods.NMHEADER)m.GetLParam(typeof(NativeMethods.NMHEADER));
开关(nmheader.nhdr.code){
案例HDN\U分区BLCLICKW:
如果(nmheader.iItem>=0&&nmheader.iItem
当然,您必须实现AutoResizeColumn()
,才能执行您想要的操作
第二步。要截取Ctrl-Shift-+,需要覆盖ProcessKeyPreview
。我会告诉你怎么做。在覆盖中,您将为每个列调用AutoResizeColumn()
替代方法
如果将
ListViewItems
构造为每个子项都是一个“W”字符串,长度与要绘制的数据相同,则控件将使用这些字符串自动计算此列。这可能是一种更简单的方法。这实际上与自动调整大小功能不同。“自动调整大小功能将在双击拆分器时调整列的大小。”我说的对吗?是的-列会自动调整为内容的正确宽度-这不是您在上述两种情况下所做的操作。在我所做的操作中,列会调整为固定宽度[之前设置]!这不是自动调整大小功能所做的。当用户双击列的调整大小手柄(或使用Ctrl+Shift++
键盘快捷键)时,自动调整大小功能仅将列调整为合适的值(基于内容)。列的大小不是固定的,但是,用户仍然可以自由地将列的大小调整为他们想要的任何宽度。
ListView ColumnList = sender as ListView;
e.Cancel = true;
e.NewWidth = ColumnList.Columns[e.ColumnIndex].Width;
protected override void WndProc(ref Message m) {
switch (m.Msg) {
case 0x4E: // WM_NOTIFY
if (!this.HandleNotify(ref m))
base.WndProc(ref m);
break;
default:
base.WndProc(ref m);
break;
}
}
protected bool HandleNotify(ref Message m) {
const int HDN_DIVIDERDBLCLICKW = (HDN_FIRST - 25);
NativeMethods.NMHEADER nmheader = (NativeMethods.NMHEADER)m.GetLParam(typeof(NativeMethods.NMHEADER));
switch (nmheader.nhdr.code) {
case HDN_DIVIDERDBLCLICKW:
if (nmheader.iItem >= 0 && nmheader.iItem < this.Columns.Count) {
this.AutoResizeColumn(nmheader.iItem);
m.Result = (IntPtr)1; // prevent the change from happening
return true;
}
break;
default:
break;
}
return false;
}