2010-10-09 1 views
10

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

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

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

ответ

11

Элегантный, как правило, не слово, которое вам подсказывает, когда вам нужно взломать способ работы собственного элемента управления 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); 
    } 
} 
+1

Хммм, это наименее опасный способ сделать это .... это работает, особенно если вы вызываете метод OnMouseDoubleClick из WndProc, когда сообщение попадает. Это обходит обработку проверки, сохраняя событие двойного щелчка, которое я хотел сделать. Благодаря! – Gareth

+0

Этот парень имеет аналогичную замену, где двойной щелчок также продолжает работать: http://blogs.msdn.com/b/hippietim/archive/2006/03/27/562256.aspx –

11

Если вы не хотите полностью отключать сообщения 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); 
    } 
} 
+0

отлично подходит для моих потребностей и отлично работает для меня, спасибо! –

2

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

Вам необходимо различать действия пользователя и действия программы для события ItemCheck. Я сделал это, добавив логическую переменную MyDoing в форму, чтобы позволить прохождение проверки на запуск программы. –

+1

Я нашел это другое решение, которое кажется еще более простым (менее грязным): http://stackoverflow.com/questions/1406887/only-change-a-listviewitems-checked-state-if-the-checkbox-is-clicked –

1

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

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 
Смежные вопросы