2015-09-25 2 views
-1

У меня есть массив структуры. Он объявлен как этотКак я могу отсортировать массив структуры?

Public SongsList as New List(Of Song) 

«Песня» это имя структуры. Он имеет 2 переменные: путь и имя; Мне интересно, как я могу отсортировать этот массив по имени.

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

Я попробовал этот

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 

Но это бросает NullReferenceException.

Это, как я добавляю детали к 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 
+0

Я отредактировал ваш q uestion, чтобы включить код, упомянутый в комментариях ответа OneFineDay; но, пожалуйста, в следующий раз попробуйте включить код, который вы пробовали, даже если он не работает. Теперь вы можете рассказать нам, как вы заполняете «SongsList»? –

+1

Почему вы вызываете '.ToString' для переменных, которые уже являются строками? – Enigmativity

+0

Дубликат [Что такое исключение NullReferenceException и как его исправить?] (Http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) –

ответ

0

Вы можете использовать лямбда-выражения. Он использует поле, которое вы выбираете в функции OrderBy. Позволяет переопределить метод ToString, чтобы сообщить Listbox, что отображать, тогда вы можете просто установить список в качестве источника данных.

Класс:

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 

Использование:

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

Я пробовал это, но это не сработало. Вот код: ListBox1.Items.Clear() дим сортируется = SongsList.OrderBy (Функция (ы) s.SongName) .ToList тусклый я As Integer Для г = 0 Для sorted.Count - 1 ListBox1 .Items.Add (sorted (i) .SongName.ToString) Next –

+0

NullReferenceException –

+0

Вы написали выше, что это 'имя' в структуре, а не' SongName'. Который из них? – OneFineDay

0

* Очень похоже на ответ OneFineDay в ...

Вам не нужен пользовательский класс, просто использовать 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