Рисунок владельца ListView и автоматическое изменение размера столбца

У меня есть ListView, использующий рисунок владельца для рисования дополнительного контента для некоторых подпунктов.

Я обнаружил, что, поскольку этот дополнительный контент занимает дополнительное место, представление списка теперь неправильно вычисляет ширину «автоматического изменения размера» столбца, и поэтому, когда кто-то автоматически изменяет размер некоторых столбцов (например, двойным щелчком по ручке изменения размера столбца) столбец изменяется так, что он становится слишком маленьким, и текст в этом представлении списка отображается с круглыми скобками (...) в конце.

Есть ли способ, которым я могу запросить представление списка, чтобы спросить меня, какого размера должны быть столбцы во время автоматического изменения размера?


person Justin    schedule 23.05.2012    source источник


Ответы (2)


Нет единого сообщения, которое сообщает вам, когда размер столбца будет автоматически изменен. Но, как вы упомянули, пользователь может вызвать это только двумя способами: двойной щелчок по разделителю и 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- +, вам нужно будет переопределить ProcessKeyPreview. Эта статья покажет вам, как это сделать. При переопределении вы должны вызвать AutoResizeColumn() для каждого столбца.

Альтернативный подход

Если вы создаете свой ListViewItems так, что каждый подэлемент представляет собой строку из «W» той же длины, что и данные, которые вы хотите нарисовать владельцем, элемент управления будет использовать эти строки для автоматического вычисления столбца this. Это может быть более простой подход.

person Grammarian    schedule 30.05.2012

Это можно сделать вручную в следующих двух сценариях:


  • Если вы хотите исправить minimumWidth и maximumWidth,

    Используйте это в событии 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;
person Writwick    schedule 23.05.2012
comment
На самом деле это не то же самое, что функция автоматического изменения размера. - person Justin; 23.05.2012
comment
Функция автоматического изменения размера изменит размер столбца при двойном щелчке по разделителю. Я прав?? - person Writwick; 23.05.2012
comment
Да, размер столбца автоматически изменяется, чтобы соответствовать ширине содержимого - это не то, что вы делаете в двух вышеупомянутых сценариях. - person Justin; 24.05.2012
comment
Столбец будет изменять размер до фиксированной ширины [установленной ранее] в том, что я делал! - person Writwick; 24.05.2012
comment
Это не то, что делает функция автоматического изменения размера. Функция автоматического изменения размера просто изменяет размер столбца до подходящего значения (в зависимости от содержимого), когда пользователь дважды щелкает маркер изменения размера для столбца (или использует сочетание клавиш Ctrl + Shift + +). Размер столбца не фиксирован, однако пользователь по-прежнему может изменять размер столбца до любой желаемой ширины. - person Justin; 24.05.2012
comment
Да, верно, но вы всегда можете рассчитать новый размер во время автоматического изменения размера в событии ColumnWidthChanging. Это просто сделает вашу работу! поэтому во время автоматического изменения размера просто e.Cancel и установите правильную ширину столбца! - person Writwick; 24.05.2012
comment
Но без возможности определить, возникает ли событие изменения ширины столбца в результате автоматического изменения размера или обычного изменения размера, изменение ширины столбца в этом событии также изменило бы ширину столбца во время обычного изменения размера, эффективно исправляя столбец ширина. - person Justin; 24.05.2012
comment
Вы можете сделать что-нибудь для этого ... Рассчитайте ширину столбца - ›проверьте, меньше ли новая ширина, а затем соответствующим образом отрегулируйте ширину столбца! - person Writwick; 24.05.2012