views:

591

answers:

2

Hello,

I'm learning WPF, so I'm kind of n00b in this. I saw some examples about how to do what I want to do, but nothing exactly...

The question: I want to bind List to ListBox. I want to do it in XAML, w/o coding in code behind. How can I achieve that?

Right now I do it that way:

<!-- XAML -->

<ListBox x:Name="FileList">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Label Content="{Binding Path=.}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

// Code behind
public MainWindow()
{
    // ...
    files = new List<string>();
    FileList.ItemsSource = files;
}

private void FolderBrowser_TextChanged(object sender, RoutedEventArgs e)
{
    string folder = FolderBrowser.Text;
    files.Clear();
    files.AddRange(Directory.GetFiles(folder, "*.txt", SearchOption.AllDirectories));
    FileList.Items.Refresh();
}

But I want to get rid of FileList.ItemsSource = files; and FileList.Items.Refresh(); in C# code.

Thanks

A: 

First, setup the binding in your listbox:

<ListBox x:Name="FileList" ItemsSource="{Binding Files}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Label Content="{Binding Path=.}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Next, make sure "Files" is a property in your DataContext (or code behind). (You can't bind to fields, only properties...)

Ideally, you'll want to make Files an ObservableCollection<T> instead of a List<T>, as well. This will allow the binding to handle adding or removing elements correctly.

If you do these two things, it should just work correctly.

Reed Copsey
Thanks. Next step [for me] will be learning how to create `ObservableLis<T> : INotifyCollectionChanged, INotifyPropertyChanged`
David
A: 

Two tricks to add to Reed's answer:

1) If all you're displaying in your list box items is a string, you can avoid the ListBox.ItemTemplate folderol by just setting ListBox.DisplayMemberPath.

2) You can set the window's DataContext to itself. For instance, give the window a name of MyWindow and set its DataContext to {Binding ElementName=MyWindow}. Now you can bind to any of its public properties. (I'm pretty sure Reed's who I learned that trick from in the first place.)

Robert Rossney
Thank you. It's an interesting approach and I surely will use it.
David