ListView Курсор меняется и мерцает

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

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

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;
    }
}

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

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

Любая помощь приветствуется.

Ян

Ответов (2)

Решение

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

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

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 будет полностью инициализирован!

На самом деле это довольно просто: удачного дня! :)

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