我试图为拖放ListBox.Selecteditems创建一个通用例程,从源中获取ListBox.SelectedItems并创建一个List(T)。 为此,我需要能够获取基础ListBox.SelectedValue的Type,并相信我能够使用以下行来实现:

Dim lbxType As Type = (sender.SelectedValue).GetType

这是上下文中的子例程:

Private Sub ListBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown
  If ListBox1.SelectedItems.Count = 0 OrElse e.Button <> Windows.Forms.MouseButtons.Right Then Return
  Dim lbxType As Type = (sender.SelectedValue).GetType
  Dim selItems As New List(Of lbxType)   <- FAILS! it fails here - will not compile
  {…more code…}
End Sub

显然,除此之外,我不知道如何创建如上代码所示的那种类型的List(Of T)的语法(请参阅标记为“ FAILS”的行)。 我知道我总是可以得到一个字符串TypeName(),然后执行一个Select / Case,但是我希望有一种更多的“模块化”方式。 任何帮助或指示将不胜感激。

非常感谢你!

编辑结果#1

Private Sub LbxTestDragStart(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown, ListBox3.MouseDown
    Dim lbx = DirectCast(sender, ListBox)
    If lbx.SelectedItems.Count = 0 OrElse e.Button <> Windows.Forms.MouseButtons.Right Then Return
    Dim dragLst = CType(GetType(List(Of )).
        MakeGenericType(lbx.SelectedItems(0).GetType()).
        GetConstructor(Type.EmptyTypes).
        Invoke(Nothing), IList)
    For Each si In lbx.SelectedItems
        dragLst.Add(si)
    Next
    lbx.DoDragDrop(dragLst, DragDropEffects.Copy)
End Sub

Private Sub Lbx_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox2.DragEnter, ListBox3.DragEnter
    Dim lbx = DirectCast(sender, ListBox)
    'we assume only one type of format in each listbox
    Dim fmt = e.Data.GetFormats(0)
    Dim fmtName As String = TypeName(e.Data.GetData(fmt(0))(0))
    e.Effect = DragDropEffects.None
    'id specific target listbox to set DD effects as this is a multi-purpose sub
    'in this select case, for testing, listbox3 is noticeably absent
    Select Case lbx.Name
        Case "ListBox1"
            'do something if ListBox1
        Case "ListBox2"
            If fmtName = "ClientLocation" Then e.Effect = DragDropEffects.Copy
    End Select
End Sub

Private Sub Lbx_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox2.DragDrop, ListBox3.DragDrop
    Dim lbx = DirectCast(sender, ListBox)
    Dim fmt = e.Data.GetFormats(0)
    Dim fmtName As String = TypeName(e.Data.GetData(fmt(0))(0))
    'setup for processing of dropped items
    Select Case lbx.Name
        Case "ListBox2"
            If fmtName = "ClientLocation" Then
                For Each item In e.Data.GetData(fmt(0))
                    lbx.Items.Add(item)
                Next
            End If
    End Select
End Sub

===============>>#1 票数:1 已采纳

正如我在评论中所述,拖放之间的时间太短,以至于真的不值得创建一个通用列表。 放置目标应检查放置的类型,以便仅接受ClientLocation项目, CircusClown接受CircusClown项目。

也就是说,这是仍然避免动态创建列表的方法( Animal是您的ClientLocation的Type代表):

Private dragList As List(Of Animal)

Private Sub lb_MouseMove(sender ...
    If lbMouseDown Then

        dragList = New List(Of Animal)
        For Each a As Animal In lb.Items
            dragList.Add(a)
        Next

        lb.DoDragDrop(dragList, DragDropEffects.Copy)
        ...

您的代码假装好像不知道ListBox中的类型是什么。 如果那可能是因为它可能是几种类型之一-也许内容发生了变化(?),那么您必须求助于Reflection

' get the Type for a List(of T)
Dim genType = GetType(List(Of ))
' get the type in the listbox
Dim t As Type = lb.SelectedItems(0).GetType() 'GetType(Animal) 
' get the "combined" type for List(of ) + ListType
Dim LType = genType.MakeGenericType(t)     ' == List(of Animal)

此时,您可以采用两种方法:

' METHOD 1: using a ctor
Dim ctor As ConstructorInfo = LType.GetConstructor(Type.EmptyTypes)
Dim theList = CType(ctor.Invoke(Nothing), IList)

' METHOD 2: using System.Activator:
Dim theList = CType(Activator.CreateInstance(LType), IList)

' EITHER WAY, xfer items - see note
For Each aa In lb.SelectedItems
    theList.Add(aa)
Next
lb.DoDragDrop(theList, DragDropEffects.Copy)

出于说明目的将其格式化。 您可以使用GetConstructor版本链接方法,并避免所有临时类型var:

Dim dragLst = CType(GetType(List(Of )).
    MakeGenericType(lb.SelectedItems(0).GetType()).
    GetConstructor(Type.EmptyTypes).
    Invoke(Nothing), IList)

注意:通常,您需要在DragDrop启动时添加鼠标悬停的项目-用户可能会期望如此。 该项目可能不是SelectedItems的一部分,他们可能只想拖动该项目。 这意味着在eX,eY下查找项目

为了简单起见,该代码仅使用SelectedItems

  ask by HumbleBeginnings translate from so

未解决问题?本站智能推荐:

1回复

从ListBox拖放多个项目

我有一个ListBox ,我希望能够单击多个项目,然后从每个选定的项目中拖动字符串。 我可以使它对于单个对象正常工作。 我只是不能让它工作超过1。 我查看了使用SelectionMode Multiple从ListBox拖放的WPF,但是它完全让我感到困惑(试图使用它,但是它不起作用,
1回复

使用目录内容填充列表框,但仅接受某些扩展名

因此,基本上,我将文件夹拖到窗体上,然后列表框填充其中的文件路径。 我设法使列表框仅接受.MP3路径,但是如何添加更多接受的扩展名? 如您在上面的最后一行所看到的,扩展名为.mp3的文件夹中的路径被接受。 如何添加更多可接受的扩展名,例如.avi,.mp4等? 我已经尝试过Li
1回复

将项目添加到ListBox后,DragDrop中的NullReferenceException

我正在尝试实现一个动态的ListBox,其中包含程序的“打开文件”。 这些文件可以从列表框拖到四个画布之一。 只要在启动程序之前在XAML中添加了项目,那一切都很好,但是,一旦我通过fileList.Items.Add(“ myitemname”)将项目添加到ListBox中,就可以了。
1回复

wpf-DragDrop在具有groupstyle的列表框中

我成功地使用了http://code.google.com/p/gong-wpf-dragdrop/中的控件库进行列表框拖动操作。但是,当我将一个项目放到具有组样式的列表框中时,会出现问题。我已经在DropInfo类中找到了这一行 始终返回null。 我的列表框绑定到Collectio
2回复

在Silverlight中从列表框拖放到列表框

我正在使用一个列表框来绑定来自数据库的数据,一旦绑定完成,就会有另一个列表框,我必须在其中拖放第一个列表框的内容。 我可以拖放它,但是在第二个列表框中什么都看不到(但是内容从第一个列表框移动到第二个列表框)。 我尝试通过对第一个列表框中的项目进行硬编码来尝试相同的事情,并且一切正常。 如果
1回复

Telerik DragDrop不起作用

我一直在开发软件,我想使用Telerik Listbox拖放。 问题是当我将一个项目从一个列表框拖放到另一个列表框时,它根本无法工作。 似乎drop事件不会触发。 我设置allowdrop= true 我添加了dragvisualprovider 我设置allo
2回复

空WPF ListBox作为放置目标

我有一个ListBox ,它是其他来源物品的放置目标。 除非有特殊情况,否则一切正常。 当ListBox没有项目时,我只能放在ListBox的边框中(我有一个触发器,因此拖动时可以看到Border)。 为了提供更大的放置区域,我将ListBox的MinHeight设置为25。拖动时
1回复

将ListView拖放到Listview(Listbox)

我正在用C#编写一个音频播放器。 现在,我想将某些项目从音乐库(ListView)拖放到播放列表(ListView或Listbox)。 这样行吗? 我正在使用Windows窗体,解决此问题的最佳方法是什么?
1回复

C#WPF拖放ListBox MVVM

我想在我的应用程序中启用拖放功能,以便能够在组件之间创建连接。 听起来并不难,但是问题是我想要它们之间进行连接的组件类型。 我希望能够建立连接的原因是能够绘制图形并计算最短路径等。 我所拥有的是一个列表框,其中的组件放置在画布上。 我使用ListBox的原因是使组件可选。 我也
3回复

WPF从具有SelectionMode = Extended的ListBox拖放

我有一个ListBox,并希望扩展选择模式。 我还想要实现拖放功能。 现在的问题是,如果在所选项目上单击鼠标,它将立即被选为单个选择而不是等待鼠标向上事件来执行此操作。 由于这种行为,开始拖动多个项目对于用户来说是准不可能的,因为他总是点击选择开始拖动,选择更改为鼠标下的项目并开始使用