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
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>
or
<ListBox x:Name="FileList" ItemsSource="{Binding Files}" DisplayMemberPath="."/>
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.
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.)
精彩评论