So I am building my first program in quite some time and have bashed my way through most of it successfully. Now I am running into a problem and need to ask some advice.
Description: I have a directory of notepad text (of lyrics and chord arrangements) files with titles formatted as follows. Songtitle-Artist-Key.txt First I browse for their directory which populates a listbox. Then after I select a song from said listbox, it populates 1 of 3 textboxes depending upon which textbox I assign it to via command buttons (some songs have up to 3 pages.) All of this works fine so far. (Future quest would be to automatically put a song with 2 or 3 pages into each respective textbox when the first one is clicked.)
Goal: I have 3 radio buttons labeled Title, Artist, and Key within a group control. These are meant to be used to sort the listbox by their respective names, Title, Artist, and Key.
Questions: Can I sort this listbox according to delimited category, or do I need to have 3 separate listboxes (and how would I keep them synchronized), or do I need to have some sort of data element involved? Any suggestions, thoughts, examples, or ideas welcome!
Edit: This says exactly what I want it to say, having read the how to ask page and having searched for over a full day, I am reopening this question.
Thanks, DiggDuggster
If you are working with an older version of vb you will not be able to use interpolated strings ($). Change to String.Format. Other explanation is in code comments.
Public Class frmSortedList
Private lstSongs As New List(Of Song)
Public SortOrder As Integer = 0
Private Sub frmSortedList_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim lstFileName As New List(Of String)
lstFileName.Add("Star Spangled Banner-Francis Scott Keyes-G.txt")
lstFileName.Add("Jailhouse Rock-Elvis Presley-F.txt")
lstFileName.Add("Macho Insecurity-Dead Kennedys-G.txt")
lstFileName.Add("(We Are) The Road Crew-Motorhead-F.txt")
lstFileName.Add("Moonlight Drive-The Doors-B.txt")
lstFileName.Add("While My Guitar Gently Weeps-The Beatles-B.txt")
lstFileName.Add("Waffle-Sevendust-G.txt")
lstFileName.Add("Don't Take Your Guns To Town-Johnny Cash-G.txt")
lstFileName.Add("Where Eagles Dare-Iron Maiden-B.txt")
lstFileName.Add("London Calling-The Clash-F.txt")
'your list will come from your Directory
'loop through you list of file names (or an array of file names
'call the constructor of Song passing the file name
'add the Song object to the list
For Each file As String In lstFileName
Dim s As New Song(file)
lstSongs.Add(s)
Next
'The ListBox will call .ToString on the objects you add
'to determine what to display
ListBox1.DataSource = lstSongs
ListBox1.ValueMember = "FileName"
'To access any of the properties of the items in the ListBox
'Cast the object stored in the ListBox back to song
Dim item As Song = CType(ListBox1.SelectedItem, Song)
Debug.Print($"Title: {item.Title}, Artist: {item.Artist}, Key: {item.MusicKey}")
'You can set the value property to any property of Song
Dim thefile As String = CStr(ListBox1.SelectedValue)
Debug.Print(thefile)
End Sub
Private Sub btnArtist_Click(sender As Object, e As EventArgs) Handles btnArtist.Click
'A little link code to sort the list
SortOrder = 1
Dim lstArtists As List(Of Song) = lstSongs.OrderBy(Function(s) s.Artist).ToList
ListBox1.DataSource = Nothing
ListBox1.DataSource = lstArtists
ListBox1.ValueMember = "FileName"
End Sub
Private Sub btnTitle_Click(sender As Object, e As EventArgs) Handles btnTitle.Click
SortOrder = 0
Dim lstTitle As List(Of Song) = lstSongs.OrderBy(Function(s) s.Title).ToList
ListBox1.DataSource = Nothing
ListBox1.DataSource = lstTitle
ListBox1.ValueMember = "FileName"
End Sub
Private Sub btnKey_Click(sender As Object, e As EventArgs) Handles btnKey.Click
SortOrder = 2
Dim lstKey As List(Of Song) = lstSongs.OrderBy(Function(s) s.MusicKey).ToList
ListBox1.DataSource = Nothing
ListBox1.DataSource = lstKey
ListBox1.ValueMember = "FileName"
End Sub
End Class
Public Class Song
Public ReadOnly Property Title As String
Public ReadOnly Property Artist As String
Public ReadOnly Property MusicKey As String
Public ReadOnly Property ShortFileName As String
Public Property FileName As String
Public Sub New(file As String)
FileName = file 'the full file name that was passed to the constructor
Dim index As Integer = file.IndexOf(".") 'Find where the extension starts
ShortFileName = file.Remove(index) 'Get rid of .txt
Dim parts As String() = ShortFileName.Split("-"c) 'Split returns and array
Title = parts(0)
Artist = parts(1)
MusicKey = parts(2)
End Sub
Public Overrides Function ToString() As String
'The ListBox calls .ToString on the objects you added
'You can return any property of combination of properties
'you want to display
'if you don't override you will get the fully qualified name of the object Argh!
Select Case frmSortedList.SortOrder
Case 0
Return ShortFileName
Case 1 'Artist
Return $"{Artist} - {Title} - {MusicKey}"
Case 2 'key
Return $"{MusicKey} - {Title} - {Artist}"
Case Else
Return ShortFileName
End Select
End Function
End Class