Data Binding là kĩ thuật dùng để tạo gắn kết giữa phần giao diện (UI) và dữ liệu thông qua phần business logic. Nhờ Data Binding, UI có thể tự động cập nhật lại để hiển thị các thay đổi trong dữ liệu.Ngoài ra, Data Binding trong WPF còn hỗ trợ các chiều khác nhau, nghĩa là các thay đổi có thể cập nhật từ UI vào dữ liệu.
Giới thiệu
Một Binding bao gồm 4 thành phần chính là: binding target, target property, binding source và một path (đường dẫn) đến giá trị cần thiết trong binding source, thông thường path này là một source property.
Ví dụ bạn muốn gắn property Name của một đối tượng Person cho property Text của một TextBox. Khi đó:
– Binding target: TextBox
– Target property: property Text của TextBox
– Binding source: đối tượng Person
-Path: đường dẫn đếnproperty Name của đối tượng Person.
Mô hình Data Binding của WPF theo hình minh họa sau:

Cần lưu ý là target property phải là một dependency property. Đa số các property của lớpUIElement đều là các dependency property. Đối với binding source, bạn có thể sử dụng bất kì đối tượng .NET nào, chẳng hạn như các đối tượng trong ADO.NET, XML hay các control trong WPF.
Binding Mode
Binding mode sẽ chỉ ra hướng mà dữ liệu sẽ được cập nhật. Bao gồm 5 giá trị từ enum BindingMode là:
Name |
Description |
OneWay |
Cập nhật target property theo source property |
TwoWay |
Cập nhật hai chiều giữa target property và source property. |
OneTime |
Khởi tạo target property từ source property. Sau đó việc cập nhật dữ liệu sẽ không được thực hiện. |
OneWayToSource |
Giống OneWay nhưng theo hướng ngược lại: cập nhật từ target property sang source property. |
Default |
Hướng binding dựa trên target property. Với target property mà người dùng có thể thay đổi giá trị (như TextBox.Text) thì nó là TwoWay, còn lại là OneWay |
Ví dụ
Giả sử tôi muốn cập nhật nội dung của một Label theo giá trị được nhập vào TextBox. Cửa sổ minh họa cho ví dụ này cần hai control chính là textBox1 và label1:
1
2
3
4
|
< StackPanel >
< TextBox x:Name = "textBox1" >Sample Text</ TextBox >
< Label x:Name = "label1" />
</ StackPanel >
|
Bản chất của việc tạo binding bao gồm 2 bước:
– Tạo một đối tượng System.Windows.Data.Binding và thiết lập các giá trị cần thiết.
– Gọi phương thức instance FrameworkElement.SetBinding() của target binding. FrameworkElement được thừa kế từ UIElement và là lớp cha của các control trong WPF. Phương thức này có tham số đầu tiên là một dependency property.
Ta tạo một binding với source binding là textBox1, target property là TextBox.Text, souce binding là label1 và source property là Label.Content.
1
2
3
4
|
Binding binding = new Binding();
binding.Source = textBox1; // or binding.ElementName = "textBox1";
binding.Path= new PropertyPath("Text");
binding.Mode = BindingMode.OneWay;
|
Thay vì phải tạo binding trong code-behind, bạn có thể tạo trong XAML theo cách thông thường sau:
1
2
3
4
5
6
7
8
|
< StackPanel >
< TextBox x:Name = "textBox1" >Sample Text</ TextBox >
< Label x:Name = "label1" >
< Label.Content >
< Binding ElementName = "textBox1" Path = "Text" Mode = "OneWay" />
</ Label.Content >
</ Label >
</ StackPanel >
|
Tuy nhiên, XAML còn hỗ trợ một dạng cú pháp gọn hơn với cùng chức năng như đoạn mã trên:
1
2
3
4
5
|
< StackPanel >
< TextBox x:Name = "textBox1" >Sample Text</ TextBox >
< Label x:Name = "label1"
Content = "{Binding ElementName=textBox1, Path=Text, Mode=OneWay}" />
</ StackPanel >
|
Kết quả:

Update Source Trigger
Với Binding Mode là TwoWay hoặc OneWayToSource, bạn có thể xác định thời điểm mà binding source sẽ được cập nhật lại thông qua property Binding.UpdateSourceTrigger. Enum UpdateSourceTrigger gồm 4 giá trị:
Member name
|
Description
|
Default |
Đa số các dependency property sẽ được dùng giá trị PropertyChanged, còn với property Text sẽ có giá trị là LostFocus. |
PropertyChanged |
Cập nhật binding source khi binding target property thay đổi. |
LostFocus |
Cập nhật binding source khi binding target mất focus. |
Explicit |
Cập nhật binding source chỉ khi bạn gọi phương thức UpdateSource. |
Ví dụ sau sẽ tự động cập nhật property Text của hai TextBox với nhau ngay khi property này bị thay đổi:
1
2
3
4
5
|
< StackPanel >
< TextBox x:Name = "textBox1" >Sample Text</ TextBox >
< TextBox x:Name = "textBox2"
Text = "{Binding ElementName=textBox1, Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</ StackPanel >
|
DataContext Property
Khái niệm Data Context tương tự như Data Source, đây là một property của FrameworkElement dùng để lưu dữ liệu cho việc hiển thị lên UI. Khi sử dụng cho data binding, DataContext sẽ được gán bằng đối tượng binding source.
Để minh họa, tôi tạo một lớp Product gồm hai property đơn giản sau:
1
2
3
4
5
|
public class Product
{
public int ID { get ; set ; }
public string Name { get ; set ; }
}
|
Trong XAML, tôi tạo một đối tượng Product với tên là myProduct trong Window.Resources, gán đối tượng myProduct cho DataContext của StackPanel, sau đó binding hai giá trị ID và Name của đối tượng Product này vào hai TextBox với property Text:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
< Window x:Class = "WpfApplication1.Window1"
xmlns:local = "clr-namespace:WpfApplication1"
Title = "Binding Demo" Height = "300" Width = "400" >
< Window.Resources >
< local:Product
x:Key = "myProduct" ID = "123" Name = "Microsoft Visual Studio" />
</ Window.Resources >
< StackPanel DataContext = "{StaticResource myProduct}" >
< TextBox Text = "{Binding Path=ID}" />
< TextBox Text = "{Binding Path=Name}" />
</ StackPanel >
</ Window >
|
Thay vì gán vào DataContext của StackPanel, bạn có thể sử dụng DataContext của Window. Các thành phần con vẫn có thể lấy được dữ liệu để sử dụng cho binding. Trong constructor của lớp Window1:
this .DataContext = new Product() { ID = 123, Name = "Microsoft Visual Studio" };
|
Và trong tài liệu XAML của Window1:
1
2
3
4
5
6
7
8
9
|
< Window x:Class = "WpfApplication1.Window1"
Title = "Binding Demo" Height = "300" Width = "400" >
< StackPanel >
< TextBox Text = "{Binding Path=ID}" />
< TextBox Text = "{Binding Path=Name}" />
</ StackPanel >
</ Window >
|
Cả hai cách làm này đều cho ra cùng kết quả:
