绑定自定义的数据类对象
在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 返回一个默认的相等比较器,用于比较此泛型自变量指定的类型。