[C#|XAML] 如何做簡單資料繫結

有時候在開發程式時,會希望程式的介面UI,資料呈現(如刪除、修改新增等等)可以隨著使用者的操作而自動對應改變,也就是說當資料被改動時,也會自動的在UI上呈現,而資料繫結的方式包含三種,One Way、Two Way 與 OneWayToSource,一般預設都是One Way方式,也就是由資料端繫結到呈現UI端,通常是因為顯示資料時是唯獨的原因。

在這邊,主要介紹如何時做一個簡單的資料繫結方式,在XAML中如何與邏輯端的資料做繫結,並實作INotifyPropertyChanged介面。

介紹

 


 

有時候在開發程式時,會希望程式的介面UI,資料呈現(如刪除、修改新增等等)可以隨著使用者的操作而自動對應改變,也就是說當資料被改動時,也會自動的在UI上呈現,而資料繫結的方式包含三種,One Way、Two Way 與 OneWayToSource,一般預設都是One Way方式,也就是由資料端繫結到呈現UI端,通常是因為顯示資料時是唯獨的原因。

在這邊,主要介紹如何時做一個簡單的資料繫結方式,在XAML中如何與邏輯端的資料做繫結,並實作INotifyPropertyChanged介面,透過DataContext或Binding物件來做連接

 

未使用資料繫結

 


 

這邊的例子是一個Employee員工輸入名稱與ID並透過繫結自動更改UI的資料,並透過Button送出更新的操作

如下是Employee的類別:

public class Employee
   {
       string name;
       int id;
       public Employee()
       {
           name = "名稱";
           id = -1;
       }
       public string Name
       {
           set
           {
               name = value;

           }
           get { return name; }
       }
       public int ID
       {
           set
           {
               id = value;

           }
           get { return id; }
       }
   }

在XAML部份有兩個TextBlock與兩個TextBox,分別名稱是showNameTextBlock、showIdTextBlock與nameText、idText等名稱

一般在送出按鈕後可能會這樣寫(em是Employee物件):

private void Button_Click(object sender, RoutedEventArgs e)
       {
           em.ID = Convert.ToInt32(idText.Text);
           em.Name = nameText.Text;

           showIdBlock.Text = em.ID.ToString();
           showNameBlock.Text = em.Name;
       }

實作INotifyPropertyChanged介面

 


 

而如果今天要做資料繫結,所先要對Employee實作INotifyPropertyChanged介面,透過這個INotifyPropertyChanged告知UI端繫結的資料更改。

using System.ComponentModel;

實作INotifyPropertyChanged

public class Employee : INotifyPropertyChanged
    {
        string name;
        int id;
        public Employee() {
            name = "名稱";
            id = -1;
        }
        public string Name
        {
            set
            {
                name = value;
                NotifyPropertyChanged("Name");
            }
            get { return name; }
        }
        public int ID
        {
            set
            {
                id = value;
                NotifyPropertyChanged("ID");
            }
            get { return id; }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); }
        }
    }

其中,NotifyPropertyChanged填入的字串是對應到XAML上要Binding的屬性名稱

 

然後在XAML部份做Binding,會看到Binding的 名稱與Employee中NotifyPropertyChanged填入的字串是要一致

<TextBlock Name="showNameTextBlock" Text="{Binding Name}" HorizontalAlignment="Left" Margin="229,360,0,0" TextWrapping="Wrap"  VerticalAlignment="Top" FontSize="30" FontFamily="Global User Interface"/>
<TextBlock Name="showIdTextBlock"   Text="{Binding ID}" HorizontalAlignment="Left" Margin="229,440,0,0" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="30"/>

 

在CodeBehind指定繫結來源

 


 

上述完成後,在來我們需要在Code的部分把UI的Control與資料端做一次連結即可

這兩有兩中方是可以使用:

 

1.透過DataContext:

DataContext可以取得或設定元素參與資料繫結時的資料內容,只要是繼承自FrameworkElement的類別都有DataContext屬性,且如果父元件有指定DataConetxt,子元件皆會繼承,特別適合用來將介面上數個目標項繫結至同一個來源時使用。

public MainPage()
       {
           this.InitializeComponent();
           em = new Employee();
           showNameTextBlock.DataContext = em;
           showIdTextBlock.DataContext = em;
       }

不過,以這個範例,這樣等於指定了兩次,我們也可以透過

this.DataContext = em;

來取代,這邊的this是視窗本身,由於此兩個TextBlock屬於視窗Windows階層之下,所以都有繼承沿用Windows元件中的DataConext,都可以繫結到此em物件來源。

 

2.透過Binding物件來設定

比起上面DataContext的方式要麻煩一點,不過有時候如果要動態一個一個指定的話,可能會需使用到

Binding binderName = new Binding()
           {
               Path = new PropertyPath("Name"),
               Mode = BindingMode.OneWay,
               Source = em
           };
           showNameTextBlock.SetBinding(TextBlock.TextProperty, binderName);
           Binding binderId = new Binding()
           {
               Path = new PropertyPath("ID"),
               Mode = BindingMode.OneWay,
               Source = em
           };
           showIdTextBlock.SetBinding(TextBlock.TextProperty, binderId);

如果使用CodeBehind的Binding物件完成指定繫結來源,也就不需要在XAML中做Text="{Binding Name}" 與 Text="{Binding ID}"了

 

data binding.zip

 

 

參考資料:

資料繫結概觀

DataContext

WPF:建立 DataContext 的幾種寫法

 


 

文章中的敘述如有觀念不正確錯誤的部分,歡迎告知指正 謝謝 =)

另外要轉載請附上出處 感謝