有時候在開發程式時,會希望程式的介面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}"了
參考資料:
文章中的敘述如有觀念不正確錯誤的部分,歡迎告知指正 謝謝 =)
另外要轉載請附上出處 感謝