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

Как сделать listview не автоматически проверять элемент, когда я дважды щелкните его?

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

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

4 ответов


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

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

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

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

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

У меня была аналогичная проблема, и вот как я с ней справился. В основном, если элемент проверен, а координата 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

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

    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's 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