【问题标题】:Vb.net Load multiple lines from a textfile to different listboxesVb.net 将文本文件中的多行加载到不同的列表框
【发布时间】:2016-05-04 06:36:00
【问题描述】:

简介

好的,我有一个load 和一个save 按钮。我要将所有listbox items 保存到.txt 文件中,然后将它们加载到列表框。

现在,如果它只是一个列表框,这将非常简单。我的问题是它有 9 个列表框,只有一个 .txt 文件包含来自 9 个列表框的所有项目。我不想要 9 个不同的 .txt 文件。请记住,列表框包含的项目数量各不相同。

这就是save 按钮输出到 .txt 文件的方式(下一个版本)

Channel 1
c:\folder\folder

Channel 2
\\server\folder\foldera
\\server\folder\folderb

Channel 3
\\anotherserver\foldera
\\anotherserver\folderb
\\anotherserver\folderc
\\anotherserver\folderd
\\anotherserver\foldere

Channel 4
\\somepath\folder\folder\foldera

Channel 5
\\server\folder\foldera

Channel 6
\\server\folder\foldera

\\server\folder\foldera

Channel 8
\\server\folder\foldera

Channel 9
\\server\folder\foldera

每个通道是列表框,路径是每个列表框包含的项目。

这是我的存档btnsave.click

Dim configfile As String = "C:\Applicationpath\Config\" & System.DateTime.Now.ToString("yyyyMMdd") & "_Config.txt"

Using fs As FileStream = File.Create(configfile)
fs.Close()
End Using

Write_Configfile()

... 和 Write_config() 执行以下操作:

    Dim objWriter As New System.IO.StreamWriter(configfile, True)
    Try
        objWriter.WriteLine("Channel 1")
        For Each itm1 As String In Me.lbchannel1.Items
            objWriter.WriteLine(itm1)
        Next
        objWriter.WriteLine(" ")

        objWriter.WriteLine("Channel 2")
        For Each itm2 As String In Me.lbChannel2.Items
            objWriter.WriteLine(itm2)
        Next
        objWriter.WriteLine(" ")

一直到第 9 频道。我知道,这可能有更简单的方法。

问题和疑问

现在转到load 按钮。我认为如果我可以从文本文件的指定部分加载每个列表框,我会很好。我想说“嘿,将所有项目添加到通道 1 (listbox1),这些项目在配置文件中的“通道 1”和“通道 2”之间写入 - 等等到通道 9。这就是我所在的位置卡住了。

我需要在某个单词之后或某些单词之间readline。没有读到某一行,因为就像我说的列表框包含的项目数量不同。

请记住,如果这样更容易,我可以将保存输出更改为如下所示:

c1:c:\folder\folder   
c2:\\server\folder\foldera
c2:\\server\folder\folderb
'and so on... 

所以我的尝试是这样的:

    If OpenFileDialog1.ShowDialog = DialogResult.OK Then

        Using reader As New StreamReader(OpenFileDialog1.FileName.ToString)
            Dim line As String = reader.ReadLine(OpenFileDialog1.FileName)
            If line = "c1:" Then
                lbchannel1.Items.Add(line) 'lbchannel1 is listbox1
            End If
            'if line = "c2:" then
            'blablabla
            'if line = "c3:" then
            'same goes to c9
        End Using
    End If

但这给了我这个错误{"Conversion from string C:\Applicationpath\Config\20160405_config.txt to type integer is not valid."},我确信这不是正确的方法。

【问题讨论】:

    标签: vb.net


    【解决方案1】:

    如果您调整列表框的名称和文本文件中的标题以使它们相等,则有一个通用的解决方案。

    更改 Write_config() 使其写入 Channel1 而不是 Channel 1 等:

    Dim objWriter As New System.IO.StreamWriter(configfile, True)
    For Each o As ListBox In Me.Controls.OfType(Of ListBox).Where(Function(c) c.Name.StartsWith("Channel"))
        objWriter.WriteLine(o.Name)
        For Each itm As String In o.Items
            objWriter.WriteLine(itm1)
        Next
    Next
    

    还将列表框控件的名称更改为 Channel1Channel9

    新的 TextFile 看起来像:

    Channel1
    c:\folder\folder
    
    Channel2
    \\server\folder\foldera
    \\server\folder\folderb
    ...
    

    现在更改填充列表框的代码:

    Using reader As New StreamReader(OpenFileDialog1.FileName.ToString)
            Dim currentListBox As ListBox = Nothing
    
            While reader.Peek > -1
                Dim line As String = reader.ReadLine()
                If Not String.IsNullOrEmpty(line) Then
                    Dim tmpListBox = Controls.Find(line, false) 'Try to find listbox according to line 
                    If tmpListBox.Any() Then 'It´s a listbox name
                       currentListBox = DirectCast(tmpListBox(0), ListBox)
                    Else 'It´s a folder name
                       currentListBox.Items.Add(line) 
                    End If
                End If
           End While
     End Using
    

    【讨论】:

    • 在您的第一个代码示例中,您只编写了 9 个通道,而不是列表框包含的内容...
    • 是的。感谢您的提示。
    • 是的,正是我想要的。像魅力一样工作。谢谢!
    • 我能看到的唯一黑点是您在遇到的每一行都查找控件...因此,如果表单中有很多控件或行中的行,它可能会慢一点文本文件
    • 我认为这里的性能不是问题。首先,我删除了 recursive 搜索,因为 listBoxes 似乎直接属于表单。其次,我创建了一个带有 5,000 控件的表单,并测量了所有 Controls.Find(line, true) 调用的总数,该调用时间为 21 毫秒,Controls.Find(line, false) 调用时间为 7 毫秒。因此,删除递归部分会稍微提高性能。无论如何,在这种情况下,读/写文本文件将花费最多的时间。
    【解决方案2】:

    对于你的保存功能,你可以使用这样的东西:

    Using objWriter As New System.IO.StreamWriter(configfile, True)
        Try
            'We will run through each channel
            For i = 1 to 9
                objWriter.WriteLine("Channel " & i.ToString())
                'We find the ListBox based on its name
                Dim LB As ListBox = CType(Me.Controls.Find("lbchannel" & i.ToString(), True), ListBox)
                For Each itm As String In LB.Items
                    objWriter.WriteLine(itm)
                Next
                objWriter.WriteLine("")
            Next
        Catch ex as Exception
            'Exception Handling here
        End Try
    End Using
    

    然后您将希望通过以下方式加载文件:

    Using reader As New StreamReader(OpenFileDialog1.FileName)
        Dim Line As String = reader.ReadLine()
        Dim CurrentChanel as Integer = 0
        Dim LB As ListBox = Nothing
        While Not IsNothing(Line) 'It will be Nothing when file is over
            If Line.StartsWith("Channel ") Then
                'We will increment CurrentChannel, as we changed the section
                CurrentChannel += 1
                LB = CType(Me.Controls.Find("lbchannel" & CurrentChannel.ToString(), True), ListBox)
            Else If Line <> "" Then
                LB.Items.Add(Line)
            End If
            Line = reader.ReadLine()
        End While
    End Using
    

    【讨论】:

      【解决方案3】:

      从您的 ReadLine 中删除文件名。 然后添加一个拆分和选择案例以确定要填充的控件。

              Using reader As New StreamReader(OpenFileDialog1.FileName.ToString)
                  Dim line As String = reader.ReadLine()
                  Dim values() As String = line.Split(":")
                  Select Case values(0)
                      Case "C1"
                          lbchannel1.items.add(values(1))
      
                      Case "C2"
                          lbchannel2.items.add(values(1))
                  End Select
      
              End Using
      

      【讨论】:

      • Case C2 : lbchannel 2 (not 1)... 另外,当有 20 个通道时,您将如何处理?选择案例很好,但通常有更好的解决方案
      猜你喜欢
      • 2012-03-20
      • 1970-01-01
      • 1970-01-01
      • 2010-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-27
      相关资源
      最近更新 更多