当前位置: 首页 > 知识库问答 >
问题:

ListView:使用鼠标拖动进行多项选择

陶胤
2023-03-14

在ListView中,我可以按下< kbd>Ctrl Shift并单击项目进行选择。但是,我想拖动鼠标来选择项目(如DataGridView)。我尝试了下面的代码,我遇到了这样的问题:

我的代码:

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

共有1个答案

姚鹤龄
2023-03-14

实际上,您需要遍历当前显示的ListView的对象,并切换与鼠标移动相交的项目的选择属性。这是一种实现方法:

声明一个名为 startPoint 的类成员:

Private startPoint As Point

处理<code>MouseDown</code>事件以设置起始位置:

Private Sub ListView1_MouseDown(sender As Object, e As MouseEventArgs) Handles ListView1.MouseDown
    Dim s = DirectCast(sender, ListView)

    If e.Button = MouseButtons.Left AndAlso
        s.Items.Count > 1 Then
        startPoint = e.Location
    End If
End Sub

处理 MouseMove 事件以切换“已选择”属性:

Private Sub ListView1_MouseMove(sender As Object, e As MouseEventArgs) Handles ListView1.MouseMove
    Dim s = DirectCast(sender, ListView)

    If e.Button = MouseButtons.Left AndAlso s.Items.Count > 1 Then
        Dim selRect As New Rectangle(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))

        Dim cr = s.ClientRectangle

        'Toggle selection...
        For Each item In s.Items.Cast(Of ListViewItem).
            Where(Function(x) x.Bounds.IntersectsWith(cr))
            item.Selected = selRect.IntersectsWith(item.Bounds)
        Next
    End If
End Sub

一个快速演示来检查:

但是,如果您有许多项目,其中客户区的大小不够大,无法显示所有项目,因此垂直滚动条是可见的,该怎么办?您将得到如下内容:

如您所见,垂直滚动条没有移动,您将无法继续选择/取消选择隐藏的项目。为了解决这个问题,我们需要更多的代码:

在类的某处导入GetScrollPos函数的签名:

Imports System.Runtime.InteropServices
'...

<DllImport("user32.dll", CharSet:=CharSet.Auto)>
Private Shared Function GetScrollPos(hWnd As IntPtr,
                                    nBar As Orientation) As Integer
End Function

注意:传递System. Windows. Forms. Ori的值而不是Interger

鼠标关闭事件更改为:

Private Sub ListView1_MouseDown(sender As Object, e As MouseEventArgs) Handles ListView1.MouseDown
    Dim s = DirectCast(sender, ListView)

    If e.Button = MouseButtons.Left AndAlso
    s.Items.Count > 1 Then
        Dim vsp = GetScrollPos(s.Handle, Orientation.Vertical)
        Dim yOffset = s.Font.Height * vsp

        startPoint = New Point(e.X, e.Y + yOffset)
    End If
End Sub

鼠标移动事件:

Private Sub ListView1_MouseMove(sender As Object, e As MouseEventArgs) Handles ListView1.MouseMove
    Dim s = DirectCast(sender, ListView)

    If e.Button = MouseButtons.Left AndAlso s.Items.Count > 1 Then
        Dim vsp = GetScrollPos(s.Handle, Orientation.Vertical)
        Dim yOffset = s.Font.Height * vsp

        Dim selRect As New Rectangle(Math.Min(startPoint.X, e.Location.X),
                                    Math.Min(startPoint.Y - yOffset, e.Location.Y),
                                    Math.Abs(e.Location.X - startPoint.X),
                                    Math.Abs(e.Location.Y - startPoint.Y + yOffset))

        Dim cr = s.ClientRectangle

        'Toggle selection...
        For Each item In s.Items.Cast(Of ListViewItem).
            Where(Function(x) x.Bounds.IntersectsWith(cr))
            item.Selected = selRect.IntersectsWith(item.Bounds)
        Next

        'Scroll if needed...
        Dim p = s.PointToClient(Cursor.Position)
        Dim lvi = s.GetItemAt(p.X, p.Y)

        If lvi Is Nothing Then Return

        Dim fh = s.Font.Height

        If lvi.Index > 0 AndAlso (p.Y - lvi.Bounds.Height * 1.5) <= fh Then
            s.Items(lvi.Index - 1).EnsureVisible()
        ElseIf lvi.Index < s.Items.Count - 1 AndAlso
            (p.Y + lvi.Bounds.Height * 1.5) > (s.Height - fh) Then
            s.Items(lvi.Index + 1).EnsureVisible()
        End If
    End If
End Sub

结果是:

下面是针对此问题的VB.NET自定义ListView控件,以及C#中的另一个控件。

 类似资料:
  • 我是JavaFX的新手,我似乎找不到如何做到这一点。 我在Vbox中有一个ListView,我用一个可见的字符串列表填充它。我已经将ListView的SelectionMode设置为MULTIPLE,这允许我在按住Ctrl或Shift键的同时选择多个项目。 我希望能够单击一行并向下拖动鼠标并选择多行,但我不知道该怎么做。我已经尝试了几次搜索,似乎只找到了拖放,这不是我需要的。

  • 我有一个带有多个选项卡的选项卡。我想通过在特定位置拖动选项卡来重新定位选项卡(就像我们能够在浏览器中排列选项卡一样。有什么办法可以实现它吗?

  • 问题内容: 因此,正如标题所述,我想在鼠标拖动时移动椭圆。我先声明了椭圆并将其画出(因为我有8个椭圆,它们带有不同的颜色信息。四个是白色,另一个是红色)。我尝试做我对矩形所做的事情: 但这似乎不起作用。它给我一个错误 我有点困惑,因为我已经阅读了文档,并且Ellipse2D.Double存在这样的变量。 这是一个MCVE: 那么是否有替代算法,或者我只是在语法上缺少什么?我想知道解决方案。谢谢。

  • 我试图改变JTable的选择行为,使其能够在不使用CTRL修饰符的情况下向选择添加和移除行。方法: 似乎正是我所要寻找的,尤其是这种情况: 是我想做的。问题是我做不到。也许我遗漏了一些关于内部JTable工作的信息,但下面是我的代码: 这似乎是在不务正业。有谁能告诉我问题出在哪里吗? 多谢了。

  • 本文向大家介绍js实现鼠标拖拽多选功能示例,包括了js实现鼠标拖拽多选功能示例的使用技巧和注意事项,需要的朋友参考一下 最近做了一个用js实现鼠标拖拽多选的功能,于是整理了一下思路,写了一个小demo: 遮罩出现: 被遮罩盖住的,即为选中的块(背景色为粉色) 下面是具体代码,注释已在文中,与大家交流。 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 如何用vscode选择多行? 在Visual Studio上,您可以按左alt键并选择多行,但它不适用于vscode。