Проблема с линиями сетки Listview

#winapi #listview #gridlines

#winapi #listview #линии сетки

Вопрос:

Возникла проблема с рисованием линий сетки в listview с помощью обычных элементов управления 6. Это происходит, когда я пытаюсь прокрутить страницу списка вниз или страницу вверх с помощью мыши.

скриншот
(источник: rsdn.ru) .

Я смог найти только это обсуждение http://www.ureader.com/msg/1484143.aspx, но решения не идеальны

  1. LVS_EX_DOUBLEBUFFER у меня не работает
  2. Отключение плавной прокрутки у меня не работает
  3. Аннулирование при прокрутке работает, но мерцание не в порядке
  4. Отключение линий сетки работает, но без них список выглядит не очень хорошо.

Есть ли какие-либо другие варианты? Спасибо!

Комментарии:

1. Вероятно, на самом деле это не вариант, но как насчет того, чтобы не полагаться на технологию 6-летней давности?

2. Даже если я использую . NET и WinForms Я столкнусь с той же проблемой, потому что WinForms полагаются на WinAPI и используют тот же Listview, что и я. И вы правы, это не вариант. Я не собираюсь переписывать все программное обеспечение. Мне просто нужно устранить проблему.

Ответ №1:

ObjectListView — оболочка с открытым исходным кодом вокруг простого .NET WinForms ListView — устраняет эту проблему (и множество других тоже).

Если вы хотите исправить это в своем собственном коде, вам необходимо прослушать отраженное уведомление о LVN_ENDSCROLL . В обработчике для конечной прокрутки сделайте что-то вроде этого:

 protected void HandleEndScroll(ref Message m) {
    // There is a bug in ListView under XP that causes the gridlines to be 
    // incorrectly scrolled when the left button is clicked to scroll. 
    // This is supposedly documented at KB 813791, but I couldn't find it. 
    if (!ObjectListView.IsVista amp;amp; 
        Control.MouseButtons == MouseButtons.Left amp;amp;
        this.GridLines) {
        this.Invalidate();
        this.Update();
    }
}
  

При этом возникает небольшое мерцание, но это намного лучше, чем полное искажение линий сетки.

Ответ №2:

Я решил создать подкласс listview и обработать сообщение WM_VSCROLL:

   WORD x=LOWORD(wParam);
  if(iMsg==WM_VSCROLL amp;amp; (x==SB_PAGEDOWN || x==SB_PAGEUP || x==SB_LINEDOWN || x==SB_LINEUP))
  {
    InvalidateRect(hDlg, 0, true);
    UpdateWindow(hDlg);
  }
  

Комментарии:

1. Преимущество использования LVN_ENDSCROLL заключается в том, что оно отправляется всякий раз, когда listview прокручивается (ну, в основном). WM_VSCROLL отправляется только при манипулировании полосой прокрутки. Использование колесика мыши для прокрутки приведет к отправке LVN_ENDSCROLL, но не WM_VSCROLL. НО эта проблема возникает только при щелчке мыши, поэтому использование сообщения WM_VSCROLL также работает нормально.

Ответ №3:

Это часто задаваемые вопросы Win32 Usenet с 2001 года, смотрите группы Google: Win32 Listview , C code (MS)

Ответ №4:

У меня есть проект, преобразованный из VB6 в MS Vs2005, в котором возникает та же проблема, когда я включаю «Включить визуальный стиль XP» в свойствах проекта -> Настройка приложения. Затем я отключаю эту функцию, и она устраняет проблему.

Комментарии:

1. Это верно, но отключение визуальных стилей XP обычно не является вариантом.

Ответ №5:

Нельзя ли просто аннулировать элемент управления и перерисовать его, когда пользователь закончит прокрутку? Я не помню точно, как это сделать, но у меня была похожая проблема раньше, и вот как я с ней справился.

Комментарии:

1. Это именно то, что я делаю. Смотрите ответы выше. В любом случае спасибо!