MadsTheMan MadsTheMan - 7 months ago 32
Vb.net Question

Vb.net Load multiple lines from a textfile to different listboxes

Intro

Alright so I have a

load
and a
save
button. I'm going to save all
listbox items
to a
.txt
file and then load them up to the listbox.

Now, this would be pretty simple if it was just one listbox. My problem is that its 9 listboxes, and just one .txt file that contains all the items from the 9 listboxes. I don't want 9 different .txt files. And keep in mind that how many items the listboxes contains varies.

This is how the
save
button outputs to the .txt file (Another version further down)

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


Each channel is the listboxes and the paths is the items that each listbox contains.

Here is my save
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()


... and
Write_config()
does the following:

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


and all the way to channel 9. There is probably a easier way to do this, I know.

The problem and question

Now to the
load
button. I thought that if I can load each listbox from a spesified part of the textfile I would be fine. I'd love to say "Hey, add all the items to channel 1 (listbox1) that are written between "Channel 1" and "Channel 2" in the configfile - and so on to channel 9. And this is where I'm stuck.

I need to
readline
after a certain word or between certain words. Not read a certain line, because like I said how many items the listboxes contains varies.

Keep in mind that I can change the save output to look like this if that makes things easier:

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


So my attempt to that have been this:

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


But this gives me this error
{"Conversion from string C:\Applicationpath\Config\20160405_config.txt to type integer is not valid."}
and I'm sure its not the correct way to do it.

Answer

If you adapt the names of your listboxes and the headings in your textfile so that they are equal, there is a generic solution for that.

Change Write_config() so that it write Channel1 instead of Channel 1 etc.:

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

Also change the names of your listbox controls to Channel1 up to Channel9.

New TextFile would look like:

Channel1
c:\folder\folder

Channel2
\\server\folder\foldera
\\server\folder\folderb
...

Now change the code for filling the listboxes:

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