Vb.net ListView:使用鼠标拖动的多选项
在ListView中,我可以按Ctrl+Shift并单击要选择的项目。但是,我想拖动鼠标来选择项目(如DataGridView)。我尝试了以下代码,但遇到了如下问题: 我的代码:Vb.net ListView:使用鼠标拖动的多选项,vb.net,listview,Vb.net,Listview,在ListView中,我可以按Ctrl+Shift并单击要选择的项目。但是,我想拖动鼠标来选择项目(如DataGridView)。我尝试了以下代码,但遇到了如下问题: 我的代码: Private mouseDownLV As Boolean Private Sub ListView1_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles ListView1.MouseDown mou
Private mouseDownLV As Boolean
Private Sub ListView1_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles ListView1.MouseDown
mouseDownLV = True
End Sub
Private Sub ListView1_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles ListView1.MouseMove
If mouseDownLV Then
Try
Dim i = ListView1.HitTest(e.Location).Item.Index
ListView1.Items(i).Selected = True
Catch ' ex As Exception
End Try
End If
End Sub
Private Sub ListView1_MouseUp(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles ListView1.MouseUp
mouseDownLV = False
End Sub
实际上,您需要遍历当前显示的
ListViewItem
对象,并切换与鼠标移动相交的项目的Selected
属性。以下是实现这一目标的方法:
声明名为startPoint
的类成员:
专用起始点作为点
处理MouseDown
事件以设置起始位置:
Private子ListView1\u MouseDown(发送方作为对象,e作为MouseEventArgs)处理ListView1.MouseDown
Dim s=DirectCast(发送方,列表视图)
如果e.按钮=鼠标按钮,则左和右
s、 项目。然后计数>1
起始点=e.位置
如果结束
端接头
处理MouseMove
事件以切换选定的属性:
Private子ListView1\u MouseMove(发送方作为对象,e作为MouseEventArgs)处理ListView1.MouseMove
Dim s=DirectCast(发送方,列表视图)
如果e.Button=MouseButtons.Left,并且s.Items.Count>1,则
Dim selRect作为新矩形(Math.Min(startPoint.X,e.Location.X),
Math.Min(startPoint.Y,e.Location.Y),
Math.Abs(e.Location.X-startPoint.X),
Math.Abs(e.Location.Y-startPoint.Y))
尺寸cr=s.ClientRectangle
'切换选择。。。
对于s.Items.Cast(属于ListViewItem)中的每个项目。
式中(函数(x)x.Bounds.与(cr)相交)
item.Selected=SELECT.IntersectsWith(item.Bounds)
下一个
如果结束
端接头
快速演示以检查:
但是,如果您有许多项目,其中客户端区域的大小不足以全部显示,因此垂直滚动条可见,该怎么办?你会得到这样的结果:
如您所见,垂直滚动条不会移动,您将无法继续选择/取消选择隐藏项。为了解决这个问题,我们需要更多的代码:
将函数的签名导入类中的某个位置:
导入System.Runtime.InteropServices
'...
专用共享函数GetScrollPos(hWnd作为IntPtr,
nBar(作为方向)作为整数
端函数
注意:传递System.Windows.Forms.Orientation
值,而不是integer
将MouseDown
事件更改为:
Private子ListView1\u MouseDown(发送方作为对象,e作为MouseEventArgs)处理ListView1.MouseDown
Dim s=DirectCast(发送方,列表视图)
如果e.按钮=鼠标按钮,则左和右
s、 项目。然后计数>1
Dim vsp=GetScrollPos(s.手柄,方向.垂直)
Dim yOffset=s.Font.Height*vsp
起始点=新点(e.X,e.Y+Y偏移)
如果结束
端接头
并将MouseMove
事件移动到:
Private子ListView1\u MouseMove(发送方作为对象,e作为MouseEventArgs)处理ListView1.MouseMove
Dim s=DirectCast(发送方,列表视图)
如果e.Button=MouseButtons.Left,并且s.Items.Count>1,则
Dim vsp=GetScrollPos(s.手柄,方向.垂直)
Dim yOffset=s.Font.Height*vsp
Dim selRect作为新矩形(Math.Min(startPoint.X,e.Location.X),
Math.Min(startPoint.Y-yOffset,e.Location.Y),
Math.Abs(e.Location.X-startPoint.X),
Abs(e.Location.Y-startPoint.Y+yOffset))
尺寸cr=s.ClientRectangle
'切换选择。。。
对于s.Items.Cast(属于ListViewItem)中的每个项目。
式中(函数(x)x.Bounds.与(cr)相交)
item.Selected=SELECT.IntersectsWith(item.Bounds)
下一个
'如果需要,请滚动。。。
Dim p=s.PointToClient(光标位置)
尺寸lvi=s.GetItemAt(p.X,p.Y)
如果lvi为空,则返回
尺寸fh=s.Font.Height
如果lvi.指数>0且也为(p.Y-lvi.Bounds.Height*1.5)(s.Height-fh),则
s、 项目(lvi.Index+1).可确保()
如果结束
如果结束
端接头
结果是:
VB.NET自定义ListView控件是否可以解决此问题,在C#中使用一列没有标题的DataGridView不是更容易吗?但是DataGridView没有ListView漂亮:((我没想到会这样!)