【问题标题】:Adding Conditions to the Listboxes from .csv files从 .csv 文件向列表框添加条件
【发布时间】:2021-09-15 06:40:58
【问题描述】:

enter image description here我正在寻找这个问题很长时间,但我没有找到任何关于它的信息...... :( 。 所以,我有 2 个 .csv 文件。在 .csv 文件 1 中是列表框,所有这些列表框都有一个介于 1 和 6 之间的数字。在 .csv 文件 2 中是一些工具,例如 (audi, bmw),这些工具也有一个介于 1 和 6 之间的数字。

例子:

.csv 文件 1

列表框 1 (X,Y,Length,Width) 类别 1

列表框 2 (X,Y,Length,Width) 类别 2

列表框 3 (X,Y,Length,Width) 类别 3


.csv 文件 2

梅赛德斯类别 1

宝马 2 类

奥迪类别 3

所以,我想比较 2 个 .csv 文件并允许列表框 2 仅用于 BMW 拖放。 如果我在列表框中将类别 2 放到类别 1 中,它应该是错误的。


Imports System.Windows.Forms
Imports System.IO

Public Class Form2

    Private meineListBoxen As New List(Of ListBox)


    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(";")

            meineListBoxen.Add(New ListBox)

            With meineListBoxen(i - 1)
                .Left = strFelder(0)
                .Top = strFelder(1)
                .Width = strFelder(2)
                .Height = strFelder(3)
            End With

            Me.Controls.Add(meineListBoxen(i - 1))
            Me.meineListBoxen(i - 1).AllowDrop = True
            AddHandler meineListBoxen(i - 1).MouseDown, AddressOf meineListbox_MouseDown
            AddHandler meineListBoxen(i - 1).DragDrop, AddressOf meineListbox_DragDrop
            AddHandler meineListBoxen(i - 1).DragEnter, AddressOf meineListbox_DragEnter
        Next
        For a As Integer = 0 To strZeilen0.GetUpperBound(0)
            Me.meineListBoxen(1 - 1).Items.Add(strZeilen0(a).Substring(0, strZeilen0(a).IndexOf(";")))
        Next
        For j As Integer = 1 To strZeilen2.GetUpperBound(0)
            strFelder1 = strZeilen2(j).Split(" ")

            With meineListBoxen(j)
                .Items.Add(strFelder1(4))

            End With
            For Each itm In meineListBoxen(j).Items
                If meineListBoxen(1 - 1).Items.Contains(itm) Then meineListBoxen(1 - 1).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 source As ListBox
    Private sourceIndex As Integer

    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
            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

        lbx = CType(sender, ListBox)
        If Not source Is Nothing Then
            source.Items.RemoveAt(sourceIndex)
        End If
        lbx.Items.Add(e.Data.GetData(DataFormats.Text))
    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
            e.Effect = DragDropEffects.All
        Else
            e.Effect = DragDropEffects.None
        End If
    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

【问题讨论】:

  • csv 代表逗号分隔值。您显示的文件内容似乎不遵循此模式。您是否准确显示了文件的内容?
  • 您需要做的第一件事是在项目属性中打开 Option Strict。还要在工具->选项->项目和解决方案->VB默认设置中设置它。
  • If aIndex &lt;= 0 Then ListBox中第一项的索引是索引0。
  • 这2个Process.Start方法有效吗?
  • 我们需要一个最小的、完整的、可重复的演示文稿来解决您的问题。见stackoverflow.com/help/minimal-reproducible-example

标签: vb.net csv drag-and-drop compare listboxitem


【解决方案1】:
Private Sub cmdSave_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Speichern.Click
    Using w As New StreamWriter("K:\Ruebel_Andreas\Modellpflege\Datenerfassung.csv")
        For i = 0 To meineListBoxen.Count - 1
            w.WriteLine(meineListBoxen.Item(i))
        Next
    End Using
End Sub

我觉得很奇怪 Handles 子句与方法的名称不匹配。默认为 Private Sub Speichern_Click

StreamWriter 需要被释放。即使出现错误,Using...End Using 块也会处理此问题。

假设您有 3 个列表框。您的循环将从索引 0 转到索引 2。WriteLine 将对ListBox 列表中的每个项目调用ToString。我不相信 ListBox 提供了 ToString 的实现,因此您将获得对象类型的完全限定名称。我不认为你想要这个。

Private Sub cmdSave_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Speichern.Click
    Using w As New StreamWriter("K:\Ruebel_Andreas\Modellpflege\Datenerfassung.csv")
        For Each LB As ListBox In meineListBoxen
            For Each item As String In LB.Items
                w.WriteLine(item)
            Next
        Next
    End Using
End Sub

您可以在声明变量时对其进行初始化,并使用 Option Infer 将它们进行强类型化(仅适用于局部变量。

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    Dim strZeilen2 = File.ReadAllLines("K:\Ruebel_Andreas\Modellpflege\Datenerfassung.csv")
    Dim strZeilen = File.ReadAllLines("K:\Ruebel_Andreas\Modellpflege\listboxpflege.csv")
    Dim strZeilen0 = File.ReadAllLines("K:\Ruebel_Andreas\Modellpflege\Spritzguss.csv")
    For i = 1 To strZeilen.GetUpperBound(0) 'Why are skipping the first line?
        Dim strFelder = strZeilen(i).Split(";"c)
        Dim LB As New ListBox
        With LB
            .Left = CInt(strFelder(0))
            .Top = CInt(strFelder(1))
            .Width = CInt(strFelder(2))
            .Height = CInt(strFelder(3))
            .AllowDrop = True
            .Name = "ListBox" & i 'In case you need to refer to the control be name
        End With
        If i = 1 Then
            For a As Integer = 0 To strZeilen0.GetUpperBound(0)
                LB.Items.Add(strZeilen0(a).Substring(0, strZeilen0(a).IndexOf(";")))
            Next
        End If
        AddHandler LB.MouseDown, AddressOf meineListbox_MouseDown
        AddHandler LB.DragDrop, AddressOf meineListbox_DragDrop
        AddHandler LB.DragEnter, AddressOf meineListbox_DragEnter
        'I fleshed out the control before adding to the collections
        Controls.Add(LB)
        meineListBoxen.Add(LB)
    Next
    For j = 1 To strZeilen2.GetUpperBound(0) 'Again skipping first line, perhaps it is a title line
        Dim strFelder1 = strZeilen2(j).Split(" "c)
        meineListBoxen(j).Items.Add(strFelder1(4)) 'You are skipping the first list box
        For Each itm In meineListBoxen(j).Items
            If meineListBoxen(0).Items.Contains(itm) Then
                meineListBoxen(0).Items.Remove(itm)
            End If
        Next
    Next
End Sub

无需定义点,只需将坐标传递给IndexFromPoint 方法即可。您可以使用DirectCast 获取ListBox,因为我们确定senderListBoxDirectCast 跳过了CType 所做的一些检查,因此该方法更快一些。我不确定是否需要检查 aIndex 的值。 Exception 处理繁重,不应用于简单的值检查。

Private Sub meineListbox_MouseDown(sender As System.Object, e As System.Windows.Forms.MouseEventArgs)
    Dim lbx = DirectCast(sender, ListBox)
    Dim aIndex = lbx.IndexFromPoint(e.X, e.Y)

    If aIndex < 0 Then
        MessageBox.Show("Bitte wählen Sie ein Werkzeug aus")
    Else
        source = lbx
        sourceIndex = aIndex
        lbx.DoDragDrop(lbx.Items(aIndex), DragDropEffects.All)
    End If
End Sub

检查空对象时使用IsNot

Private Sub meineListbox_DragDrop(sender As System.Object, e As System.Windows.Forms.DragEventArgs)
    Dim lbx = DirectCast(sender, ListBox)
    If source IsNot Nothing Then
        source.Items.RemoveAt(sourceIndex)
    End If
    lbx.Items.Add(e.Data.GetData(DataFormats.Text))
End Sub

一遍又一遍地更新这个标签只会减慢速度。删除此子。

'Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
    'lblMaus.Text = "X: " & e.X & " , Y: " & e.Y
'End Sub

如果没有您文件中的正确数据,我将无能为力。有一次,您用分号分割,而您的样本数据中没有任何内容!您显示的文件内容肯定不是 CSV 文件。

【讨论】:

    猜你喜欢
    • 2021-09-30
    • 1970-01-01
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多