本文主要研究ListBox的绑定,一般来说,ListBox常用的绑定属性是ItemsSource和SelectedItem,但是本文讨论的是其他两个属性:SelectedValue, SelectedValuePath。下面这个程序很有意思,改变左侧的选中项,右侧的选中项会跟着变,下面2个TextBox里面的内容也会显示出选中的内容。例如我选中了"Mike",右侧自动选中了"Dog",下面两个TextBox分别显示,Mike 和 Dog:
下面是“人类”和“动物”两个类型,各自有2个属性,其中一个属性是共同的——ID:
class Human
{
public int ID { get; set; }
public string Name { get; set; }
}
class Animal
{
public int ID { get; set; }
public string Category { get; set; }
}
下面是XAML的定义,很简单,只是把TextBox绑定到了各自的ListBox中:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="252" Width="370">
<Grid Height="205" Width="341">
<Grid.RowDefinitions>
<RowDefinition Height="168*" />
<RowDefinition Height="37*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="176*" />
<ColumnDefinition Width="165*" />
</Grid.ColumnDefinitions>
<ListBox Grid.Row="0" Grid.Column="0" Name="lsLeft" />
<ListBox Grid.Row="0" Grid.Column="1" Name="lsRight" />
<TextBox Grid.Row="1" Grid.Column="0" Name="txtLeft" Text="{Binding Path=SelectedItem.Name, ElementName=lsLeft}" />
<TextBox Grid.Row="1" Grid.Column="1" Name="txtRight" Text="{Binding Path=SelectedItem.Category, ElementName=lsRight}"/>
</Grid>
</Window>
以下是代码,People和Animals是两个集合,分别放入了4个Human和6个Animal对象。他们的ID都是连续的,并且都从1开始。下面的代码把2个集合绑定到了2个ListBox,ListBox的DisplayNamePath分别设置成Name和Category属性,但是SelectedValuePath都设置成ID。但是,最关键的一点是,左侧的ListBox右侧的相绑定,而中间的桥梁是SelectedValue属性!
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private List<Human> People;
private List<Animal> Animals;
public MainWindow()
{
People = new List<Human>();
People.Add(new Human() { ID = 1, Name = "Tom" });
People.Add(new Human() { ID = 2, Name = "Jerry" });
People.Add(new Human() { ID = 3, Name = "Mike" });
People.Add(new Human() { ID = 4, Name = "Lee" });
Animals = new List<Animal>();
Animals.Add(new Animal() { ID = 1, Category = "Cat" });
Animals.Add(new Animal() { ID = 2, Category = "Tiger" });
Animals.Add(new Animal() { ID = 3, Category = "Dog" });
Animals.Add(new Animal() { ID = 4, Category = "Pig" });
Animals.Add(new Animal() { ID = 5, Category = "Cook" });
Animals.Add(new Animal() { ID = 6, Category = "Cow" });
InitializeComponent();
lsLeft.ItemsSource = People;
lsLeft.DisplayMemberPath = "Name";
lsLeft.SelectedValuePath = "ID";
lsRight.ItemsSource = Animals;
lsRight.DisplayMemberPath = "Category";
lsRight.SelectedValuePath = "ID";
Binding binding = new Binding();
binding.ElementName = "lsRight";
binding.Path = new PropertyPath("SelectedValue");
lsLeft.SetBinding(ListBox.SelectedValueProperty, binding);
}
}
上面的代码之所以能work,就是因为ListBox的SelectedValuePath设置为ID属性,所以每个选中的Item其SelectedValue就是ID属性,一旦两个ListBox的SelectedValue都一致的话,绑定就自动生效,当左侧Mike (ID=3)被选中,右侧Dog(ID=3)就自动被选中,同理,选中右侧的Cat,左侧的Tom也同样被选中。但是假如你选中右侧的Cook或者Cow,那么左侧就没有一个被选中,下方的TextBox的内容也是空。可见,左侧的SelectedItem被设置成了null。
在实际项目中,有时候可能会使用到这个技术,比如,注册论坛注册,允许用户选择不同的内置头像,一旦用户选定,数据库中会保存头像的ID(肯定不是头像的内容吧),那么头像肯定另有一张数据库表来维护,具有ID,图片路径等。然而,当用户需要修改头像的时候,你需要在ComboBox里面列出所有的内置头像,然后把该用户原先选择的头像默认选中。要实现这个功能的话,就需要用到ID的绑定,就可以使用本文的方法~