ListView所有者绘图和列自动调整大小

时间:2012-05-23 15:53:29

标签: c# listview autoresize

我有ListView使用所有者绘图为某些子项目绘制其他内容。

我发现因为这个额外的内容占用了一些额外的空间,列表视图现在错误地计算列“自动调整大小”宽度,所以当有人自动调整某些列时(例如通过双击列调整大小句柄) )调整列的大小,使其太小,并在列表视图中的文本最后用父对象(...)呈现。

有没有办法可以提示列表视图询问我在自动调整大小时列的大小?

2 个答案:

答案 0 :(得分:1)

没有单个消息告诉您何时要自动调整列的大小。但正如您所提到的,用户只能通过两种方式触发:双击分隔符和Ctrl-Shift-+。你可以拦截这两个,然后做你喜欢的任何事情。

步骤1:要拦截双击,您需要继承ListView并听取HDN_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;
}

当然,您必须实施AutoResizeColumn()来做您想做的事。

步骤#2。要拦截Ctrl-Shift- +,您需要覆盖ProcessKeyPreviewThis article会告诉你如何做到这一点。在您的覆盖中,您可以为每列调用AutoResizeColumn()

替代方法

如果构造ListViewItems使得每个子项是与您想要所有者绘制的数据长度相同的“W”字符串,则控件将使用这些字符串自动计算此列。这可能是一种更简单的方法。

答案 1 :(得分:0)

您可以在以下两个场景中手动执行此操作:


  • 如果您要修复minimumWidthmaximumWidth

    ColumnWidthChanging

  • ListView事件中使用此功能
   int minimumWidth = 200;
   int maximumWidth = 500;
   if (e.NewWidth  maximumWidth)
   {
      e.Cancel = true;
      e.NewWidth = maximumWidth;
   }

  • 如果您要为ColumnWidth修正ListViewColumn,请设置 所需的ColumnWidth

    ColumnWidthChanging

  • ListView事件中使用此功能
   ListView ColumnList = sender as ListView;
   e.Cancel = true;
   e.NewWidth = ColumnList.Columns[e.ColumnIndex].Width;