#winapi #listview #gridlines
#winapi #listview #линии сетки
Вопрос:
Возникла проблема с рисованием линий сетки в listview с помощью обычных элементов управления 6. Это происходит, когда я пытаюсь прокрутить страницу списка вниз или страницу вверх с помощью мыши.
(источник: rsdn.ru) .
Я смог найти только это обсуждение http://www.ureader.com/msg/1484143.aspx, но решения не идеальны
- LVS_EX_DOUBLEBUFFER у меня не работает
- Отключение плавной прокрутки у меня не работает
- Аннулирование при прокрутке работает, но мерцание не в порядке
- Отключение линий сетки работает, но без них список выглядит не очень хорошо.
Есть ли какие-либо другие варианты? Спасибо!
Комментарии:
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. Это именно то, что я делаю. Смотрите ответы выше. В любом случае спасибо!