WPF資料繫結-簡單物件的繫結
繫結自定義的資料類物件
在xaml程式碼中,Binding標記擴充套件中僅定義了Path屬性,將它繫結到StudentData類的屬性上。不需要定義源物件,因為通過指定DataContext類定義源物件。
DataContext是一個依賴屬性,它用基於FramewrokElement定義。指定相應控制元件的DataContext屬性表示當前控制元件中的每個元素都預設繫結此資料。
xaml程式碼
<Window x:Class="BindingDemo.Window2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window2" Height="300" Width="300"> <Grid> <!-- 簡單物件的繫結 --> <StackPanel Name="stackPanel" HorizontalAlignment="Left" VerticalAlignment="Top" Orientation="Vertical"> <Label Name="lbId" Content="{Binding ID}"/> <Label Name="lbName" Content="{Binding Name}"/> <Label Name="lbAge" Content="{Binding Age}"/> </StackPanel> </Grid> </Window>
資料類 namespace BindingDemo { public class StudentData { public int ID { get; set; } public string Name { get; set; } public int Age { get; set; } } }
隱藏程式碼 public partial class Window2 : Window { public Window2() { InitializeComponent(); Init(); } public void Init() { StudentData stuData = new StudentData(); stuData.ID = 1001; stuData.Name = "小明"; stuData.Age = 18; //this.DataContext = stuData;//整個視窗內的所有元素都可以繫結此資料 stackPanel.DataContext = stuData;//僅stackPanel內的所有元素可以繫結此資料 } }
以上綁定當修改資料內容時介面顯示是不會更改的,要實現更改資訊傳遞給使用者介面,資料類必須實現INotifyPropertyChanged介面。
該介面定義了ProperytChanged事件,該事件在OnPropertyChagned方法中觸發。
xaml程式碼
<Window x:Class="BindingDemo.Window2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window2" Height="300" Width="300"> <Grid> <!-- 簡單物件的繫結 --> <StackPanel Name="stackPanel" HorizontalAlignment="Left" VerticalAlignment="Top" Orientation="Vertical"> <Label Name="lbId" Content="{Binding ID}"/> <Label Name="lbName" Content="{Binding Name}"/> <Label Name="lbAge" Content="{Binding Age}"/> <Button Name="btnChang" Content="按鈕" Click="btnChang_Click"/> </StackPanel> </Grid> </Window>
資料類
namespace BindingDemo { public class StudentData : INotifyPropertyChanged { private int _id = 0; private string _name = ""; private int _age = 0; public int ID { get { return _id; } set { _id = value; OnPropertyChanged("ID"); } } public string Name { get { return _name; } set { _name = value; OnPropertyChanged("Name"); } } public int Age { get { return _age; } set { _age = value; OnPropertyChanged("Age"); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { if(PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } }
隱藏程式碼 public partial class Window2 : Window { public Window2() { InitializeComponent(); Init(); } private StudentData stuData; public void Init() { stuData = new StudentData(); stuData.ID = 1001; stuData.Name = "小明"; stuData.Age = 18; //this.DataContext = stuData;//整個視窗內的所有元素都可以繫結此資料 stackPanel.DataContext = stuData;//僅stackPanel內的所有元素可以繫結此資料 } private void btnChang_Click(object sender, RoutedEventArgs e) { stuData.ID = 1002; stuData.Name = "小紅"; stuData.Age = 17; } }
此時執行程式點選按鈕更改資訊時發現使用者介面顯示的資料也跟著重新整理了。下面的內容是對上面的資料類做的進一步封裝。最終效果是一樣的。
先建立一個實現INotifyPropertyChanged介面的一個抽象類基類BindableObject,資料類只需要繼承此抽象基類自然就實現了介面INotifyPropertyChanged
namespace BindingDemo { public abstract class BindableObject : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } protected void SetProperty<T>(ref T item,T value,[CallerMemberName] string propertyName=null) { if(!EqualityComparer<T>.Default.Equals(item,value)) { item = value; OnPropertyChanged(propertyName); } } } }
namespace BindingDemo { public class StudentData : BindableObject { private int _id = 0; private string _name = ""; private int _age = 0; public int ID { get { return _id; } set { SetProperty(ref _id,value); } } public string Name { get { return _name; } set { SetProperty(ref _name, value); } } public int Age { get { return _age; } set { SetProperty(ref _age, value); } } } }
[CallerMemberName]獲取呼叫方的屬性或方法名稱
EqualityComparer<T> T為要比較的物件的型別
EqualityComparer<T>.Default 返回一個預設的相等比較器,用於比較此泛型自變數指定的型別。