目录
一、概述
二、Data Binding在WPF中的地位
三、Binding基础
程序的本质是数据加算法,用户给进一个输入,经过算法的处理程序会反馈一个输出-这里,数据处于程序的核心地位。反过来再看“UI驱动程序”,数据处于被动地位,总是在等待程序接收来自UI的消息/事件后被处理或者算法完成后处理后被显示。如何在GUI编程时把数据的地位由被动变主动、让数据回归程序的核心呢?这就是本文详解的内容。
在从传统的WinForm迁移到WPF之后,对于一个三层程序而言,数据存储层由数据库和文件系统来构建,数据传输和处理仍然使用NET Framwork 的ADO.NET等基本类,展示层则使用WPF类库来实现,而展示层与逻辑层的沟通就使用Data Binding来实现。可见,Data Binding在WPF系统中起到的是数据高速公路的作用。
引入Data Binding机制后,好处有很多。首先,数据在逻辑层和用户界面之间“直来直去”、不涉及逻辑问题,用户界面部分几乎不包含算法。再次,所有的业务逻辑相关的算法都处在数据逻辑层,逻辑层成为一个能够独立运转的,完整的体系。
Binding更注重表达它是一种像桥梁一样的关联关系。如果Binding比作的数据的桥梁,那么它的两端分别是Binding的源(Source)和目标(Target)。一般情况下,Binding源是逻辑层的对象,Binding目标是UI层的控件对象,数据就会源源不断通过Binding送达UI层、被UI层展现,也就完成了数据驱动UI的过程。
简单实例
首先,我们创建一个名为student的类,这个类将作为数据源来使用。
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
这个类很简单,只有一个Name属性。光有属性还不行,Binding是一种自动机制,当值变化后属性要有能力通知Binding,让Binding把变化传递给UI元素。怎样具备这种能力,方法是在属性的set语句中激发一个PropertyChanged事件。这个事件不需要我们自己声明,我们要做的是让座位数据源的类实现INotifyPropertyChanged接口。当为Binding设置了数据源后,Binding就会自动侦听来自这个接口的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元素显示新的值。
然后,我们在窗体上准备一个TextBox和一个Button。TextBox将作为Binding的目标,我们还会在Button的Click事件发生时改变Student对象的Name属性值。
XAML代码如下:
接下来,我们将进入最重要的一步,使用Binding把数据源和UI元素连接起来。cs的代码如下:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace WpfApp1
{
///
/// MainWindow.xaml 的交互逻辑
///
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";
}
}
}
把数据源和目标连接在一起的任务是使用BindingOperations.SetBinding()方法完成的。这个方法的3个参数说明如下:
第一个参数用于指定Binding的目标。第二个参数用于为Binding指明把数据送达目标的那个属性。第三个参数指定使用哪个Binding实例将数据源于目标关联起来。