程序的本质是数据加算法,这一点我们在控制台应用中已经能充分体会到,用户给进一个输入,经过算法的处理,程序会反馈一个输出。在这个过程中,数据处于主导,核心地位。然而,自从GUI程序越来越受人们青睐以来,基于UI的“消息驱动”或者“事件驱动”却将数据放到了被动的地位,在一个GUI程序中,数据总是在等待一个事件的触发后才会被处理,同时等待算法执行完后才能在UI控件上显示。如何在GUI编程中把数据的地位从被动变为主动,让数据回归到程序的核心呢?WPF为我们推出了Data Binding机制。
应用程序会具有三层结构,即数据存储层、数据处理层和数据展示层。Binding机制作用在处理层和展示层之间,Binding就像是一座桥梁,它的两端分别是数据的源(source)和目标(target),数据从哪里来那里就是源,Binding是中间的桥梁,Bingding目标是数据要往那里去。一般情况下,Binding源是逻辑层的对象,目标是UI层的控件对象,这样,数据就会不断的通过Binding送达UI层,被UI层展现,也就完成了数据驱动UI的过程。
在大致了解了Binding的概念后,让我们看一个例子来更形象的了解它。
1、首先创建一个名为Student的类,用这个类作为数据源来使用。Student对象有很多属性,那么那个数据是你想通过Binding送达给UI元素,即UI上的元素最关心的是那个属性值的变化,这个属性就是Binding的路径(Path)但,光有属性还不够,因为Binding是一种自动机制,当值变化后,属性要有能力告诉Binding,让Binding把变化传递给UI元素,这就要在属性的Set语句中激发一个PropertyChanged事件。当为Binding设置了数据源后,Binding就会自动侦听这个事件
// student数据源,实现INotifyPropertyChanged接口,从而侦听PropertyChanged事件
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事件就会被激发,Binding接收到这个事件后发现事件的消息告诉它是名为Name的属性发生了值的变化,于是会通知Binding目标端的UI元素显示新的值。
2、XAML界面的呈现,窗体上一个Textbox控件作为Binding目标,一个Button控件是为了触发事件来改变Textbox的Name属性值
<Window x:Class="WPFBindingLearn.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>
3、接下来就是使用Binding将数据源和UI元素连接起来
public partial class MainWindow : Window
{
Student stu;
public MainWindow()
{
InitializeComponent();
//准备数据源
stu = new Student();
//准备Binding
Binding binding = new Binding();
binding.Source = stu;
binding.Path = new PropertyPath("Name");
//使用Binding连接数据源于Binding目标
BindingOperations.SetBinding(this.textBoxName, TextBox.TextProperty, binding);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
stu.Name += "Name";
}
}
通过为Binding设置数据源,设定访问路径;通过SetBinding()方法实现数据源和目标的连接。该方法的三个参数:
第一个参数用于指定Binding的目标,本例中为textBoxName
第二个参数用于指定将数据送达到目标的那个属性
第三个参数就是用一个binding实例将数据源和目标关联起来
点击运行,就可以看到