26

I've ran into a bit of a wall with being able to bind data of my custom object list to a ListBox in WPF.

This is the custom object:

public class FileItem
{
    public string Name { get; set; }
    public string Path { get; set; }
}

And this is the list:

private List<FileItem> folder = new List<FileItem>();
public List<FileItem> Folder { get { return folder; } }

The list gets populated and maintained by a FileSystemWatcher as files get moved around, deleted, renamed, etc. All the list does is keeps tracks of names and paths.

Here's what I have in the MainWindow code-behind file (it's hard coded for testing purposes for now):

FolderWatcher folder1 = new FolderWatcher();
folder1.Run(@"E:\MyApp\test", "*.txt");

listboxFolder1.ItemsSource = folder1.Folder;

Here's my XAML portion:

<ListBox x:Name="listboxFolder1" Grid.Row="1" BorderThickness="0" 
         ItemsSource="{Binding}"/>

Unfortunately, the only thing that gets displayed is MyApp.FileItem for every entry. How do I display the specific property such as name?

0

4 Answers 4

45

You will need to define the ItemTemplate for your ListBox

    <ListBox x:Name="listboxFolder1" Grid.Row="1" BorderThickness="0" 
     ItemsSource="{Binding}">
       <ListBox.ItemTemplate>
         <DataTemplate>
           <TextBlock Text="{Binding Name}"/>
         </DataTemplate>
       </ListBox.ItemTemplate>
     </ListBox>
Sign up to request clarification or add additional context in comments.

Comments

22

The easiest way is to override ToString on your FileItem, (The listbox uses this to populate each entry)

    public override string ToString()
    {
        return Name;
    }

2 Comments

Thank you, it works. I liked XAML version better, but this one did the job as well and like you said -- it's simple. I just wanted to keep ToString() open for other things that may require return of path name or a combination of.
The difference is this will work when showing multiple list boxes :) no worries
10

Each item in the list that ListBox shows automatically calls the ToString method to display it, and since you didn't override it, it displays the name of the type.

So, there are two things you can do here.

  1. Override the ToString method like Sayse suggested.
  2. Use DataTemplate and bind each of your properties seperatly

In your resource add the template with a key

        <DataTemplate x:Key="fileItemTemplate">
            <StackPanel>
                <TextBlock Text="{Binding Name}"/>
                <TextBlock Text="{Binding Path}"/>
            </StackPanel>
        </DataTemplate>

and give it as your listbox ItemTemplate

<ListBox x:Name="listboxFolder1" Grid.Row="1" BorderThickness="0"  ItemsSource="{Binding}" ItemTemplate="{StaticResource fileItemTemplate}">

1 Comment

Thank you very much for the link, that guy knows how to explain things clearly.
4

In case anyone comes across this now via search, I just encountered pretty much the same issue in a C# UWP app.

While the XAML bits in Nitin's answer above were necessary, they didn't fix the issue alone -- I also had to change my equivalent of Folder to be an ObservableCollection, rather than a List, to get the ListBox to show the property I needed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.