Winforms ListView - Остановить автоматическую проверку при двойном щелчке

Как сделать listview автоматически не проверять элемент при двойном щелчке по нему?

Я могу попробовать подключиться к событию MouseDoubleClick и установить свойство Checked в false, но это похоже на взлома. Я также выполняю разумно дорогостоящий расчет, когда элемент действительно проверен, и не хотите, чтобы этот код запускался с двойным щелчком. При запуске события выше события ItemCheck и ItemChecked поднимаются перед обработкой двойного щелчка.

Есть ли элегантное решение?

Ответ 1

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

Добавьте новый класс в свой проект и вставьте код, показанный ниже. Компиляция. Отбросьте новый элемент управления сверху панели инструментов на форму.

using System;
using System.Windows.Forms;

class MyListView : ListView {
    protected override void WndProc(ref Message m) {
        // Filter WM_LBUTTONDBLCLK
        if (m.Msg != 0x203) base.WndProc(ref m);
    }
}

Ответ 2

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

public class NoDoubleClickAutoCheckListview : ListView
{
    private bool checkFromDoubleClick = false;

    protected override void OnItemCheck(ItemCheckEventArgs ice)
    {
        if (this.checkFromDoubleClick)
        {
            ice.NewValue = ice.CurrentValue;
            this.checkFromDoubleClick = false;
        }
        else
            base.OnItemCheck(ice);
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        // Is this a double-click?
        if ((e.Button == MouseButtons.Left) && (e.Clicks > 1)) {
            this.checkFromDoubleClick = true;
        }
        base.OnMouseDown(e);
    }

    protected override void OnKeyDown(KeyEventArgs e)
    {
        this.checkFromDoubleClick = false;
        base.OnKeyDown(e);
    }
}

Ответ 3

У меня была аналогичная проблема, и именно так я справился с ней. В основном, если элемент проверяется, когда координата курсора x больше, чем координата x, я отменяю чек (потому что это означает, что проверка была вызвана, когда пользователь дважды щелкнул элемент).

Предел ошибки с номером 22 - это только если пользователь дважды щелкает сразу после этого флажка (очень сложно сделать).

ПРИМЕЧАНИЕ. Мой код предполагает, что пользователь не будет дважды щелкнуть по флажку (либо пользователь дважды нажимает на элемент, либо делает один щелчок на флажке)

Код ошибки находится в VB:)

Private Sub lvComboLists_ItemCheck(ByVal sender As Object, ByVal e As System.Windows.Forms.ItemCheckEventArgs) Handles lvComboLists.ItemCheck
    Dim i As Integer = CType(sender, ListView).PointToClient(Cursor.Position).X
    If i > 22 Then
        e.NewValue = e.CurrentValue
    End If
End Sub

Ответ 4

Я использую гораздо более простой способ просто сбросить значение флажка в исходное состояние, изменив его на противоположное тому, что он в настоящее время:

    Private Sub lst_Images_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles lst_Images.DoubleClick
        Dim fIndex As Integer = Me.lst_Images.SelectedIndices(0)
        ' Undo the changing of the checkbox state by the double click event. 
        lst_Images.Items(fIndex).Checked = Not lst_Images.Items(fIndex).Checked

        ' Call the viewer form
        Dim fViewer As New Image_Edit(fIndex)
        fViewer.ShowDialog()
        fViewer.Dispose()
End Sub