WPF – Data Binding cơ bản

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ớp UIElement đề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:

<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.

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:

<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:

<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:

<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:

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:

<Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        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:

<Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        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ả:

https://yinyangit.wordpress.com

Advertisements

10 thoughts on “WPF – Data Binding cơ bản

  1. Pingback: Cơ bản về MVVM (Model – View – ViewModel) Pattern « Nguyễn Ngọc Vạn's Blog

  2. Em chào tác giả!
    Tác giả có thể giúp em vấn đề này được không ạ?
    Ở WindowsForm thì e cũng không biết và sử dụng Binding và hiện tại em có đang làm một đồ án về WPF và thấy sử dụng Binding rất tiện lợi. Em đọc bài viết của tác giả cũng không được hiểu cho lắm vì e mới bắt đầu tìm hiểu về Binding nên rất mong được sự giúp đỡ của tác giả.
    Hiện tại e có một Datagrid và một CSDL SQL Server. Vậy tác giả có thể hướng dẫn em cách lấy dữ liệu từ các bảng trong CSDL sang Datagrid bằng việc sử dụng Binding được không ạ?
    Cảm ơn tác giả. Chúc tác giả luôn vui vẻ và thành công!!!

    Trả lời
  3. Pingback: Giới thiệu về MVVM (Model – View – ViewModel) Pattern « Cuộc Sống Và Khoa Học

  4. Binding binding = new Binding();
    binding.Source = textBox1; // or binding.ElementName = “textBox1”;
    binding.Path= new PropertyPath(“Text”);
    binding.Mode = BindingMode.OneWay;
    Đoạn lênh này không có đối tượng đích , mình thêm vào
    binding.TargetNullValue = Label1;
    nó cũng k chạy , làm sao ad ?

    Trả lời
  5. Cho mình hỏi cái này, mình có đoạn code ntn bây giờ mình muốn in ra một chuỗi vào textbox khi bấm vào button thì mình phải viết ntn để lấy dữ liệu ra, mình mới tự học C# lên không biết mong bạn và mọi người giúp đỡ.
    Code:
    public MainViewModel()
    {

    MSPCollection = new ObservableCollection();

    MSPCollection.Add(new MSP() {
    Id = 1,
    Name = “abcdef”
    });

    MSPCollection.Add(new MSP()
    {
    Id = 2,
    Name = “huhuhuhuhuh”
    });

    MSPCollection.Add(new MSP()
    {
    Id = 3,
    Name = “hahahahahahah”
    });

    MSPCollection.Add(new MSP()
    {
    Id = 4,
    Name = “ffffffffffffffffff”
    });
    MSPCollection.Add(new MSP()
    {
    Id = 5,
    Name = “hjhjhjhjhjhj”
    });

    …………………………
    Mình muốn in ra là ID theo thứ tự 1-2-3-4-5

    Trả lời
  6. Pingback: Cơ bản về MVVM (Model – View – ViewModel) Pattern – nguyenleblog

Trả lời

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s