-1

I have an array of a structure. It's declared like this

Public SongsList as New List(Of Song)

"Song" it's structure's name. It has 2 variables : path and name; I'm wondering how I can sort this array by the name.

Public Structure Song
  Public Path as String
  Public Name as String
End Structure

I tried this

ListBox1.Items.Clear()
Dim sorted = SongsList.OrderBy(Function(s) s.Name).ToList 
Dim i As Integer 
For i = 0 To sorted.Count - 1
    ListBox1.Items.Add(sorted(i).Name.ToString) 
Next

But it throws a NullReferenceException.

This is how I'm adding items to SongsList

Dim open As New OpenFileDialog
open.Title = "Add songs"
open.Filter = "MP3 Files(*.mp3)|*.mp3"
open.Multiselect = True
ListBox1.Items.Clear()
If open.ShowDialog = DialogResult.OK Then
    For Each SelectedSong As String In open.FileNames
        i += 1
        Dim songToAdd As New Song
        songToAdd.Path = SelectedSong.ToString
        songToAdd.Name = GetSafeFileName(SelectedSong.ToString)
        SongsList.Add(songToAdd)
        ListBox1.Items.Add(SongsList(i).Path)
    Next
End If
Cosmin Stoian
  • 19
  • 1
  • 8
  • I edited your question to include the code you mentioned in the comments of OneFineDay's answer; but please next time try to include the code you have tried - even if it didn't work. Now, can you tell us how do you fill `SongsList`? – Josh Part Sep 25 '15 at 23:48
  • 1
    Why do you call `.ToString` on variables which are already strings? – Enigmativity Sep 26 '15 at 03:25
  • Duplicate of [What is a NullReferenceException and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Bjørn-Roger Kringsjå Sep 26 '15 at 07:40

2 Answers2

0

You can use a Lambda expression. It uses the field you select in the OrderBy function. Lets Override the ToString method to tell the Listbox what to display, then you can just set the list as the datasource.

The class:

Public Class Song
  Public Property Path as String
  Public Property Name as String
  Public Overrides Function ToString() As String
    Return Me.Path
  End If
End Class

Usage:

Dim open As New OpenFileDialog
open.Title = "Add songs"
open.Filter = "MP3 Files(*.mp3)|*.mp3"
open.Multiselect = True
If open.ShowDialog = DialogResult.OK Then
  For Each SelectedSong As String In open.FileNames
    Dim songToAdd As New Song
    songToAdd.Path = SelectedSong
    songToAdd.Name = GetSafeFileName(SelectedSong.ToString)
    SongsList.Add(songToAdd)
   Next
End If
Listbox1.DataSource = SongsList.OrderBy(Function(s) s.Name).ToList
OneFineDay
  • 9,004
  • 3
  • 26
  • 37
0

*Very similar to OneFineDay's answer...

You don't need a custom class, just use a List(Of FileInfo):

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim open As New OpenFileDialog
    open.Title = "Add songs"
    open.Filter = "MP3 Files(*.mp3)|*.mp3"
    open.Multiselect = True
    If open.ShowDialog = DialogResult.OK Then
        ListBox1.DataSource = Nothing
        Dim songs As New List(Of FileInfo)
        For Each SelectedSong As String In open.FileNames
            songs.Add(New FileInfo(SelectedSong))
        Next
        songs = songs.OrderBy(Function(fi) fi.Name).ToList
        ListBox1.DataSource = songs
        ListBox1.DisplayMember = "Name"
        ListBox1.ValueMember = "FullName"
    End If
End Sub

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    If ListBox1.SelectedIndex <> -1 Then
        Dim fi As FileInfo = DirectCast(ListBox1.SelectedItem, FileInfo)
        Dim name As String = fi.Name
        Dim fullPath As String = fi.FullName
        Debug.Print("name = " & name)
        Debug.Print("fullPath = " & fullPath)
    End If
End Sub
Idle_Mind
  • 38,363
  • 3
  • 29
  • 40