你的位置:首页 > ASP.net教程

[ASP.net教程]WPF学习09:数据绑定之 Binding to List Data


    从WPF学习03:Element Binding我们可以实现控件属性与控件属性的绑定。

    从WPF学习07:MVVM 预备知识之数据绑定 我们可以实现控件属性与自定义对象属性的绑定。

    而以上两个功能在实际应用中还是不够的,我们经常需要将列表数据与控件属性进行绑定。

 

例子

     ListBox切换人物,下面两个文本框跟随切换,很常用的功能。

    imageimage

    XAML代码:

<Window x:Class="DataTemplate.MainWindow"    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    ="http://schemas.microsoft.com/winfx/2006/xaml"    Title="MainWindow" Height="350" Width="525">  <StackPanel>    <ListBox IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding}" DisplayMemberPath="Name"/>    <StackPanel HorizontalAlignment="Center" Orientation="Horizontal">      <TextBlock Text="性别:"></TextBlock>      <TextBlock Text="{Binding Gender}" Margin="0 0 100 0"></TextBlock>      <TextBlock Text="年龄:"></TextBlock>      <TextBlock Text="{Binding Age}" Margin="0 0 100 0"></TextBlock>    </StackPanel>  </StackPanel></Window>

    后台代码:

public class Person : INotifyPropertyChanged{  public event PropertyChangedEventHandler PropertyChanged;  private void Notify(String propertyName)  {    if (PropertyChanged != null)      PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));  }  private Int32 age;  public Int32 Age  {    get { return age; }    set    {      age = value;      Notify("Age");    }  }  private String gender;  public String Gender  {    get { return gender; }    set    {      gender = value;      Notify("Gender");    }  }  private String name;  public String Name  {    get { return name; }    set    {      name = value;      Notify("Name");    }  }}class People : List<Person>{  public People()  {    this.Add(new Person() { Name = "John", Age = 30, Gender = "Male" });    this.Add(new Person() { Name = "Jake", Age = 26, Gender = "Male" });    this.Add(new Person() { Name = "Kate", Age = 25, Gender = "Female" });  }}public MainWindow(){  InitializeComponent();  DataContext = new People();}

 


 

Collection View

    将例子做一些改动:

    image

    仅仅是改动了XAML。删掉了原有的ListBox,增加了一个TextBlock与两个Button

<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">  <TextBlock Text="姓名:"></TextBlock>  <TextBlock Text="{Binding Name}" Margin="0 0 100 0"></TextBlock>  <TextBlock Text="性别:"></TextBlock>  <TextBlock Text="{Binding Gender}" Margin="0 0 100 0"></TextBlock>  <TextBlock Text="年龄:"></TextBlock>  <TextBlock Text="{Binding Age}"></TextBlock></StackPanel>

     数据绑定设置的路径为Name Gender Age 而当前的数据上下文却是个列表。在这种情况出现时,WPF会尝试当前数据列表的Current Item 视作绑定源。从而有了图片上的效果。

     通过CollectionViewSource提供的GetDefaultView方法我们可以获得列表视图,列表视图可以使我们对列表进行包括但不限于改变Current Item的操作。

     我们为两个按钮添加Handler,即可实现按钮切换人物的功能:

private void BtnToRight_Click(object sender, RoutedEventArgs e){  var view = CollectionViewSource.GetDefaultView(DataContext);  view.MoveCurrentToNext();  //越界,返回  if (view.IsCurrentAfterLast)    view.MoveCurrentToPrevious();}private void BtnToLeft_Click(object sender, RoutedEventArgs e){  var view = CollectionViewSource.GetDefaultView(DataContext);  view.MoveCurrentToPrevious();  //越界,返回  if (view.IsCurrentBeforeFirst)    view.MoveCurrentToNext();}

     获取了列表视图后,我们还可以对数据列表进行过滤,排序等操作。在此略去例子。


 

IsSynchronizedWithCurrentItem

    再回到文章最开始的例子中。之所以可以通过点击ListVox中的元素就能实现两个文字框内容的切换有两个原因:

    1.他们的数据绑定,源相同(当前数据上下文)。

    2.配置IsSynchronizedWithCurrentItem为 ture。

    这样,ListControl可在SelectedItem切换时,自动切换当前绑定列表的CurrentItem。


 

DataTemplate简介

    因为数据模板的东西太多,无法一次说完,在此先给出一个数据模板的例子。

    通过数据模板,我们可以自由的定义数据的显示内容。

    继续对本文开头的例子进行修改。首先要去掉该元素的DisplayMemberPath属性,该属性指定了绑定对象的哪一个属性做为Item的显示绑定对象。与数据模板功能冲突,故而去之。

    改动后的效果:

    image

    改动后的XAML代码:

<Window x:Class="DataTemplate.MainWindow"    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    ="http://schemas.microsoft.com/winfx/2006/xaml"    Title="MainWindow" Height="350" Width="525">  <ListBox IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding}">    <ListBox.ItemTemplate>      <DataTemplate>        <StackPanel HorizontalAlignment="Center" Orientation="Horizontal">          <TextBlock Text="姓名:"></TextBlock>          <TextBlock Text="{Binding Name}" Margin="0 0 100 0"></TextBlock>          <TextBlock Text="性别:"></TextBlock>          <TextBlock Text="{Binding Gender}" Margin="0 0 100 0"></TextBlock>          <TextBlock Text="年龄:"></TextBlock>          <TextBlock Text="{Binding Age}"></TextBlock>        </StackPanel>      </DataTemplate>    </ListBox.ItemTemplate>  </ListBox></Window>