2009-02-27 3 views
4

Я пытаюсь изменить курсор, который появляется в стандартном ListView, когда курсор появляется над элементом. Однако я получаю мерцающий эффект, когда мышь изменена на указатель пальца, а затем обратно к тому, что я просил.ListView Cursor change & мерцание

Я пытаюсь изолировать это мерцание/переход к ручному курсору, но не могу понять, где это происходит или как его остановить. Чтобы воспроизвести это ...

1) Создайте форму с ListView на ней. 2) Добавьте список изображений и некоторые изображения. Установите режим просмотра большого значка. 3) Добавьте некоторые элементы в ListView.

Добавить MouseMove событие в ListView:

private void listView1_MouseMove(object sender, MouseEventArgs e) 
{ 
    ListViewItem selected = this.listView1.GetItemAt(e.X, e.Y); 
    if (selected == null) 
    { 
     base.Cursor = Cursors.Default; 
    } 
    else 
    { 
     base.Cursor = Cursors.No; 
    } 
} 

Выполнить приложение, перемещая мышь по элементу. Вы должны видеть, что курсор мерцает между No (no entry cursor) и указателем пальца, когда вы находитесь над элементом. Вопрос в том, как убедиться, что он просто отображает курсор «Нет» и не мерцает. (C# .NET).

Я попробовал переопределить как OnMouseMove, так и OnMouseHover для возврата, чтобы гарантировать, что они ничего не устанавливают. Я также попытался переопределить свойство Cursor и сказать, что «установлен только по умолчанию или без курсоров», и это тоже не сработало.

Любая помощь с благодарностью.

Ян

+0

Это происходит в другом месте? Например, при навигации по гиперссылкам или в других приложениях? Или это * только * произойдет в вашем приложении? Если это так, вероятно, это проблема с ОС ... – Razzie

+0

Это кроссплатформенная платформа, кросс-приложение. Если вы прочтете мой комментарий на teknohippy ... Проблема преувеличена ручным рисованием предметов и hottracking. Я попытался переопределить WndProc, чтобы вернуть, если (m.Msg == 0x020) изменить курсор. Что-то переключает его на руку, но я не уверен, что. – Ian

+0

У вас есть свойство активации ListView? Если это OneClick, тогда сам элемент управления будет менять курсор на курсор руки, когда вы наводите курсор на элемент. – EricLaw

ответ

7

Проблема в том, что C# ListView Control в основном представляет собой оболочку вокруг окна управления списком окон. Поэтому, когда мы устанавливаем курсор на стрелку, основной элемент управления listview всегда по умолчанию имеет значение «Ручной», в то время как наш параметр в классе C# ListView хотел, чтобы он был стрелкой. Вот почему мы стали мерцать, потому что базовый контроль возвращался обратно в руки.

Вот код, который нужно добавить:

public const uint LVM_SETHOTCURSOR = 4158; 

[DllImport("user32.dll")] 
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); 

SendMessage(listView1.Handle, LVM_SETHOTCURSOR, IntPtr.Zero, Cursors.Arrow.Handle); 

Это очень важно, что вы называете SendMessage из OnLoad события вашей формы, потому что к тому времени основной контроль ListView полностью инициализирован!

Это довольно просто, отлично провести время! :)

+0

MTG. Спасибо за это, я посмотрю на это и попробую. Если это сработает, это станет ответом на будущее :) Я предполагаю, что другим способом было бы переопределить WndProc, используя тот же uint ... – Ian

+0

Переопределение WndProc ничего не сделает. SendMessage используется как способ обновления свойств Windows Common Control. LVM_SETHOTCUROSR - свойство Не сообщение Windows, поэтому переопределение wndproc вообще не поможет. – 2009-03-29 10:57:05

+0

Очень хорошо. Могу ли я спросить, откуда вы нашли эту информацию? Никогда не нашел приятного места, чтобы найти все эти магические постоянные значения ... – Ian

0

Без попробовав, курсоры, как правило, изменяется в ответ на WM_ SetCursor, поэтому, возможно, вы находитесь в конфликте с умолчанию обработки с WM_ SetCursor в ListView. Я попытался бы создать новый UserControl, полученный из ListView, а затем поймать WM_ SETCURSOR в WndProc и посмотреть, поможет ли это.