一、基本知识
1、Data Binding作用:Data Binding在WPF系统中起到数据高速公路的作用,有了这条高速公路,加工好的数据会自动送达到用户界面加以显示,被用户修改过的数据也会自动回传逻辑层。
数据绑定就是将数据和图形用户界面(GUI)上的控件元素关联起来,起到用户可以通过用户界面上的控件元素对数据进行操作的目的。传统的数据绑定是后台代码与GUI的控件元素属性进行交互,使用功能数据绑定减少了代码量。
2、组成:WPF中的绑定完成了绑定源和绑定目标的联动。一个绑定常常由四部分组成:绑定源、路径、绑定目标及目标属性,同时转换器也是一个非常重要的组成。
(1)Binding的源
Binding的源就是数据的源头,数据的源头只要是一个对象,并且通过属性公开自己的数据,即可作为Binding的源。
Binding的源总结:
- 把普通CLR类型单个对象指定为Source。包括.NET Framework自带类型的对象和用户自定义类型的对象。
- 把普通CLR集合类型对象指定为Source。包括数组、List<T>、ObservableCollection<T>等集合类型。
- 把ADO.NET数据对象指定为Source。包括DataTable和DataView对象。
- 把依赖对象指定为Source。
- 把容器DataContext指定为Source。
1)把控件作为Binding 源与Binding 标记扩展
<Window x:Class="testBinding2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel>
<TextBox x:Name="textBox1" Text="{Binding Path=Value,ElementName=slider1}"/>
<Slider x:Name="slider1" Maximum="100" Minimum="0"/>
</StackPanel>
</Grid>
</Window>
<TextBox x:Name="textBoxName" BorderBrush="Black" Margin="5" />使用Binding标记扩展语法,等价于C#
this.textBox.SetBinding(TextBox.TextProperty,new Binding("Value"){ ElementName="slider1"});
2)使用集合对象作为列表控件的ItemsSource
WPF中列表式控件派生自ItemsControl类,自然继承了ItemsSource属性,这个属性可以接收一个IEnumerable接口派生类的实例作为自己的值。注意:使用集合类型作为列表控件的ItemsSource时一般考虑使用ObservableCollection<T>代替List<T>,因为ObservableCollection<T>类继承实现了INotifyCollectionChanged和INotifyPropertyChanged接口,能把集合的变化立即通知显示它的列表控件,改变会立即显示出来。
应用举例:
前台代码:
<Window x:Class="testBinding2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel>
<TextBlock Text="Student ID:" FontWeight="Bold" Margin="5" />
<TextBox x:Name="textBoxId" Margin="5"/>
<TextBlock Text="Student List:" FontWeight="Bold" Margin="5"/>
<ListBox x:Name="listBoxStudents" Height="180" Margin="5"/>
<!--<ListBox.ItemTemplate>
</ListBox.ItemTemplate>-->
</StackPanel>
</Grid>
</Window>
后台代码:
namespace testBinding2
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
List<Student> stuList = new List<Student>()
{
new Student() { Id = 0, Name = "Tim", Age = 29 },
new Student() { Id = 1, Name = "Tom", Age = 28 },
new Student() { Id = 2, Name = "Kyle", Age = 27 },
new Student() { Id = 3, Name = "Tony", Age = 24 },
new Student() { Id = 4, Name = "Vina", Age = 23 },
new Student() { Id = 5, Name = "Mike", Age = 22 },
};
//为ListBox设置Binding
this.listBoxStudents.ItemsSource = stuList;//数据源
this.listBoxStudents.DisplayMemberPath = "Name";//路径
//为TextBox设置Binding
Binding binding = new Binding("SelectedItem.Id") { Source=this.listBoxStudents};
this.textBoxId.SetBinding(TextBox.TextProperty,binding);
}
}
//创建一个名为Student的类,它具有Id、Name、Age三个属性
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
}
效果:
2)Binding 的数据流方向(绑定的模式)
默认情况下,数据既能通过Binding送达目标,也能够从目标返回源。控制Binding数据流向的属性是Mode,它的类型是BindingMode,枚举为 TowWay ,OneWay,OnTime、OneWayToSource和Default。
OneWay(常规数据流):数据来源是一个数据集合,目标是一个控件元素。
TowWay:数据来源和目标任意发生改变时都更新数据来源和目标。
(2)Binding 的路径
Binding 的Path属性指定Binding源的对象哪个属性。如上所示 Slinder控件对象当做源,把它的Value属性作为路径。
特殊:没有Path的Binding ,即Binding源的本身就是数据。
二、应用
点击button按钮时TextBox控件的内容改变
1、界面设计
<Window x:Class="testBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel>
<TextBox x:Name="textBoxName" BorderBrush="Black" Margin="5" />
<Button Content="Add Age" Margin="5" Click="Button_Click"/>
</StackPanel>
</Grid>
</Window>
2、后台设计
using System.ComponentModel;
namespace testBinding
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
Student stu;
public MainWindow()
{
InitializeComponent();
//准备数据源
stu = new Student();
//准备Binding
Binding binding = new Binding();//创建Binding实例
binding.Source = stu;//指定数据源
binding.Path = new PropertyPath("Name");//指定访问路径
//使用Binding 连接数据源与Bingding目标
BindingOperations.SetBinding(this.textBoxName,TextBox.TextProperty,binding);//使用binding实例将数据源与目标关联起来
//参数为 目标;目标的某个属性
}
private void Button_Click(object sender, RoutedEventArgs e)
{
stu.Name+="Name11";
}
}
class Student:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string name;
public string Name
{
get { return name; }
set
{
name = value;
if(this.PropertyChanged!=null)
{
this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Name"));//当Name的属性值发生改变时,PropertyChanged事件触发
}
}
}
}
}