Winforms ListView – 双击时停止自动检查

双击时,如何使列表视图不自动检查项目?

我可以尝试挂钩到MouseDoubleClick事件,并将Checked属性设置为false,但这感觉有点像黑客。 在实际检查项目时,我还运行了相当昂贵的计算,并且不希望此代码在双击时运行。 上面的事件挂钩,在处理双击之前会引发ItemCheck和ItemChecked事件。

有没有一个优雅的解决方案?

当你必须破解原生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); } } 

如果您不想完全关闭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); } } 

我有类似的问题,这就是我处理它的方式。 基本上如果在光标的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