Loreno Loreno - 3 months ago 9
C# Question

WPF: Can't get a list of selected files in ListBox

Here's my problem:

I have a ListBox, to which I add items after I click a button:

var files = System.IO.Directory.GetFiles("c:\", "*.csv");

foreach (var file in files)
{
string fileName = System.IO.Path.GetFileNameWithoutExtension(file);
Settings.AllFilesList.Add(new CsvFile(fileName));
FilesListListBox.Items.Add(fileName);
}


It works as it should.

Now, my ListBox (FilesListListBox) has SelectionMode set to "Multiple".
What I need now is the ability to save the selected files in a list called SelectedFilesList. As you can see above, all files are stored in a list called AllFilesList.

How can I do that?

i tried:

private void Button_Click_2(object sender, RoutedEventArgs e)
{
foreach (var file in FilesListListBox.SelectedItems)
{
Settings.SelectedFilesList.Add(file);
}
}


but it didn't work. I think that in the foreach loop above, every file object is just a string containing a name of the file, so that's why it doesn't work. My SelectedFilesList need objects of type CsvFile.

public class CsvFile
{
public string Name { get; set; }

public CsvFile(string name)
{
Name = name;
}
}

Answer

Instead of just adding the file name in the list add the CsvFile. To do that change the way you fill the FilesListListBox to:

var files = System.IO.Directory.GetFiles("c:\\", "*.csv");

foreach (var file in files)
{
    string fileName = System.IO.Path.GetFileNameWithoutExtension(file);
    var csvFile = new CsvFile(fileName);
    Settings.AllFilesList.Add(csvFile);
    FilesListListBox.Items.Add(csvFile );
}

And then just add DisplayMemberPath to the FilesListListBox so it displays the name instead of doing ToString() of the CsvFile.

FilesListListBox.DisplayMemberPath = "Name";

or you can do it in XAML:

<ListBox Name="FilesListListBox" DisplayMemberPath="Name" />

EDIT

And this is how you add the items to your collection latter:

private void Button_Click_2(object sender, RoutedEventArgs e)
{
    foreach (CsvFile file in FilesListListBox.SelectedItems)
    {
        Settings.SelectedFilesList.Add(file);
    }
}

Or if you want to do it in one row and assuming Settings.SelectedFilesList supports AddRange using Linq:

Settings.SelectedFilesList.AddRange(FilesListListBox.SelectedItems.Cast<CsvFile>());