基于CSV文件数据为ListBox列表框添加拖拽操作的分类匹配限制
实现方案
我们只需要新增两个分类映射字典存储关联关系,再调整拖拽校验逻辑即可实现需求:
1. 新增全局分类映射
在窗体类顶部新增两个私有字典,分别存储ListBox对应的分类、工具项对应的分类:
' 存储每个ListBox对应的分类编号 Private listBoxKategorie As New Dictionary(Of ListBox, Integer) ' 存储每个工具项对应的分类编号 Private werkzeugKategorie As New Dictionary(Of String, Integer)
2. 加载CSV时填充映射
在Form_Load事件中,读取CSV时同步填充两个映射字典:
- 读取CSV1(listboxpflege.csv)创建ListBox时,存入每个ListBox的分类编号(假设CSV1第五列<索引4>为分类值)
- 读取CSV2(Spritzguss.csv)加载工具项时,存入每个工具对应的分类编号(假设CSV2第二列<索引1>为分类值)
3. 调整拖拽校验逻辑
修改DragEnter事件实现拖拽时实时校验分类,不符合要求直接禁止拖拽:
Private Sub meineListbox_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) If e.Data.GetDataPresent(DataFormats.Text) Then Dim draggedTool = e.Data.GetData(DataFormats.Text).ToString() Dim targetListBox = CType(sender, ListBox) ' 校验拖拽项和目标列表分类是否一致 If werkzeugKategorie.ContainsKey(draggedTool) AndAlso listBoxKategorie.ContainsKey(targetListBox) Then If werkzeugKategorie(draggedTool) = listBoxKategorie(targetListBox) Then e.Effect = DragDropEffects.Move Exit Sub End If End If End If e.Effect = DragDropEffects.None End Sub
同时在DragDrop事件中增加二次校验,避免异常操作:
Private Sub meineListbox_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Dim lbx As ListBox = CType(sender, ListBox) Dim draggedTool = e.Data.GetData(DataFormats.Text).ToString() ' 二次校验分类合法性 If werkzeugKategorie(draggedTool) <> listBoxKategorie(lbx) Then MessageBox.Show("仅允许拖拽到同分类的列表中") Exit Sub End If If Not source Is Nothing Then source.Items.RemoveAt(sourceIndex) End If lbx.Items.Add(draggedTool) End Sub
额外注意:原代码中MouseDown事件的If aIndex <= 0判断存在逻辑错误,会导致除第一个项外其他项无法触发拖拽,建议修改为If aIndex >= 0
完整修改后代码
Imports System.Windows.Forms Imports System.IO Public Class Form2 Private meineListBoxen As New List(Of ListBox) ' 新增分类映射 Private listBoxKategorie As New Dictionary(Of ListBox, Integer) Private werkzeugKategorie As New Dictionary(Of String, Integer) Private source As ListBox Private sourceIndex As Integer Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load Dim strZeilen() As String Dim strFelder() As String Dim strZeilen0() As String Dim strZeilen2() As String = IO.File.ReadAllLines("K:\Ruebel_Andreas\Modellpflege\Datenerfassung.csv") Dim strFelder1() As String strZeilen = File.ReadAllLines("K:\Ruebel_Andreas\Modellpflege\listboxpflege.csv") strZeilen0 = IO.File.ReadAllLines("K:\Ruebel_Andreas\Modellpflege\Spritzguss.csv") For i As Integer = 1 To strZeilen.GetUpperBound(0) strFelder = strZeilen(i).Split(";"c) Dim newListBox As New ListBox With newListBox .Left = CInt(strFelder(0)) .Top = CInt(strFelder(1)) .Width = CInt(strFelder(2)) .Height = CInt(strFelder(3)) .AllowDrop = True End With ' 存储ListBox对应分类 listBoxKategorie.Add(newListBox, CInt(strFelder(4))) meineListBoxen.Add(newListBox) Me.Controls.Add(newListBox) AddHandler newListBox.MouseDown, AddressOf meineListbox_MouseDown AddHandler newListBox.DragDrop, AddressOf meineListbox_DragDrop AddHandler newListBox.DragEnter, AddressOf meineListbox_DragEnter Next ' 加载工具项并存储工具分类 For a As Integer = 0 To strZeilen0.GetUpperBound(0) Dim toolArr = strZeilen0(a).Split(";"c) Dim toolName = toolArr(0) Dim toolCate = CInt(toolArr(1)) werkzeugKategorie(toolName) = toolCate Me.meineListBoxen(0).Items.Add(toolName) Next For j As Integer = 1 To strZeilen2.GetUpperBound(0) strFelder1 = strZeilen2(j).Split(" "c) With meineListBoxen(j) .Items.Add(strFelder1(4)) End With For Each itm In meineListBoxen(j).Items If meineListBoxen(0).Items.Contains(itm) Then meineListBoxen(0).Items.Remove(itm) Next Next End Sub Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove Me.lblMaus.Text = "X: " & e.X & " , Y:" & e.Y End Sub Private Sub meineListbox_MouseDown(ByVal sendre As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Dim aPoint As Point Dim lbx As ListBox Dim aIndex As Integer lbx = CType(sendre, ListBox) aPoint = New Point(e.X, e.Y) aIndex = lbx.IndexFromPoint(aPoint) Try ' 修复原逻辑错误,索引>=0才是有效选中项 If aIndex >= 0 Then source = lbx sourceIndex = aIndex lbx.DoDragDrop(lbx.Items(aIndex), DragDropEffects.All) End If Catch ex As Exception MessageBox.Show("Bitte wählen Sie ein Werkzeug aus") End Try End Sub Private Sub meineListbox_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Dim lbx As ListBox = CType(sender, ListBox) Dim draggedTool = e.Data.GetData(DataFormats.Text).ToString() ' 二次校验分类 If werkzeugKategorie(draggedTool) <> listBoxKategorie(lbx) Then MessageBox.Show("仅允许拖拽到同分类的列表中") Exit Sub End If If Not source Is Nothing Then source.Items.RemoveAt(sourceIndex) End If lbx.Items.Add(draggedTool) End Sub Private Sub meineListbox_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) If e.Data.GetDataPresent(DataFormats.Text) Then Dim draggedTool = e.Data.GetData(DataFormats.Text).ToString() Dim targetListBox = CType(sender, ListBox) If werkzeugKategorie.ContainsKey(draggedTool) AndAlso listBoxKategorie.ContainsKey(targetListBox) Then If werkzeugKategorie(draggedTool) = listBoxKategorie(targetListBox) Then e.Effect = DragDropEffects.Move Exit Sub End If End If End If e.Effect = DragDropEffects.None End Sub Private Sub cmdSave_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Speichern.Click Dim w As New IO.StreamWriter("K:\Ruebel_Andreas\Modellpflege\Datenerfassung.csv") For i = 0 To meineListBoxen.Count - 1 w.WriteLine(meineListBoxen.Item(i)) Next w.Close() End Sub Private Sub WerkzeugHinzufügen_Click(sender As Object, e As EventArgs) Handles WerkzeugHinzufügen.Click Process.Start("K:\Ruebel_Andreas\Modellpflege\Spritzguss.csv") End Sub Private Sub StellplatzHinzufügen_Click(sender As Object, e As EventArgs) Handles StellplatzHinzufügen.Click Process.Start("K:\Ruebel_Andreas\Modellpflege\listboxpflege.csv") End Sub End Class
内容的提问来源于stack exchange,提问作者erin karakaş
相关产品推荐
相关产品推荐

