Можно ли подавить событие DoubleClicked в ListView, когда оно вызывается правой кнопкой мыши? - PullRequest
0 голосов
/ 23 апреля 2019

Таблица здесь демонстрирует, что событие DoubleClick возникает, когда пользователь дважды щелкает левой или правой кнопкой мыши на TreeView или ListView; Я только хочу, чтобы это событие вызывалось двойным щелчком левой кнопки мыши. Замечания здесь показывают, что DoubleClick повышается до MouseDoubleClick, поэтому отменить или замкнуть DoubleClicked.

невозможно.

Тогда логически может показаться, что правильным решением является использование MouseDoubleClick, а не DoubleClick, а замечания для прежнего состояния:

События DoubleClick являются логически высокоуровневыми событиями элемента управления. Они могут быть вызваны другими действиями пользователя, такими как сочетания клавиш.

... что, по-видимому, подразумевает, что я на самом деле должен использовать DoubleClick, но, опять же, я не могу, потому что это не позволяет мне игнорировать или отменять двойной щелчок правой кнопкой мыши.

Существует ли относительно простой способ предотвратить срабатывание DoubleClick при двойном щелчке правой кнопкой мыши, или мне нужно немного испачкаться и вручную обрабатывать сообщения Windows?

1 Ответ

0 голосов
/ 23 апреля 2019

ОБНОВЛЕНО

Это происходит в void WndProc(ref Message m).Я пытался воспроизвести проблему с другим контролем (PictureBox).Двойной щелчок левой кнопкой мыши дал:

protected virtual void WndProc(ref Message m)
{
    // ...
    switch (m.Msg)
    {
        // ...
        case 514:
            WmMouseUp(ref m, MouseButtons.Left, 1);
            return;
        // ...
    }
    // ...
}

А двойной щелчок правой кнопкой мыши привел к вызову:

protected virtual void WndProc(ref Message m)
{
    // ...
    switch (m.Msg)
    {
        // ...
        case 517:
            WmMouseUp(ref m, MouseButtons.Right, 1);
            return;
        // ...
    }
    // ...
}

Где void WmMouseUp(ref Message m, MouseButtons button, int clicks) выглядит так:

private void WmMouseUp(ref Message m, MouseButtons button, int clicks)
{
    // ...
    OnDoubleClick(new MouseEventArgs(button, 2, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
    OnMouseDoubleClick(new MouseEventArgs(button, 2, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
    // ...
}

Оба OnDoubleClick и OnMouseDoubleClick огонь с MouseEventArgs.Вот почему это решение работает.

private void control_DoubleClick(object sender, EventArgs e)
{
    if ((e as MouseEventArgs)?.Button == MouseButtons.Right)
        return;

    // do your stuff
}

Но ситуация отличается от ListView:

protected virtual void WndProc(ref Message m)
{
    // ...
    switch (m.Msg)
    {
        // ...
        case 514:
        case 517: // m.Msg value
        case 520:
        {
            NativeMethods.LVHITTESTINFO lvhi = new NativeMethods.LVHITTESTINFO();
            int indexOfClickedItem = GetIndexOfClickedItem(lvhi);
            if (!base.ValidationCancelled && listViewState[262144] && indexOfClickedItem != -1)
            {
                listViewState[262144] = false;
                OnDoubleClick(EventArgs.Empty);
                OnMouseDoubleClick(new MouseEventArgs(downButton, 2, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
            }
            if (!listViewState[524288])
            {
                OnMouseUp(new MouseEventArgs(downButton, 1, NativeMethods.Util.SignedLOWORD(m.LParam), NativeMethods.Util.SignedHIWORD(m.LParam), 0));
                listViewState[1048576] = false;
            }
            ItemCollectionChangedInMouseDown = false;
            listViewState[524288] = true;
            base.CaptureInternal = false;
            return;
        }
        // ...
    }
    // ...
}

Он запускает OnDoubleClick с EventArgs.Empty.Поэтому первое решение не не работает.

В качестве обходного пути можно использовать исправленный ListView:

public class PatchedListView : ListView
{
    protected override void WndProc(ref Message m)
    {
        var suppress = m.Msg == 517 &&
                       Enum.TryParse(typeof(ListView).GetField("downButton", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this).ToString(),
                                     out MouseButtons mouseButtons) &&
                       mouseButtons == MouseButtons.Right;
        if (suppress)
            return;

        base.WndProc(ref m);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...