INotifyPropertyChanged 接口
INotifyPropertyChanged 接口用于向客户端(通常是执行绑定的客户端)发出某一属性值已更改的通知。
例如,考虑一个带有名为 FirstName 属性的 Person 对象。 若要提供一般性属性更改通知,则 Person 类型实现 INotifyPropertyChanged 接口并在FirstName 更改时引发 PropertyChanged事件。
若要在将客户端与数据源进行绑定时发出更改通知,则绑定类型应具有下列任一功能:
-
实现 INotifyPropertyChanged 接口(首选)。
-
为绑定类型的每个属性提供更改事件。
下面是一个在Silverlight中使用INotifyPropertyChanged接口的简单例子:
XAML代码如下:
<UserControl x:Class="INotifyPropertyChangedDemo.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="100" d:DesignWidth="300" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<sdk:Label HorizontalAlignment="Left" Margin="10,0" Name="lblUserName" Content="姓名:" />
<sdk:Label HorizontalAlignment="Left" Margin="10,0" Name="lblAge" Content="年龄:" Grid.Row="1" />
<TextBox Height="23" Margin="60,0,0,0" Name="txtUserName" Width="120" Text="{Binding Path=UserName}" HorizontalAlignment="Left" />
<TextBox Height="23" Margin="60,0,0,0" Name="txtAge" Width="120" Text="{Binding Path=Age}" Grid.Row="1" HorizontalAlignment="Left" />
<Button Height="23" Margin="200,0,0,0" Name="btnHandle" Width="75" Content="更改" Grid.Row="1" HorizontalAlignment="Left" Click="btnHandle_Click" />
</Grid>
</UserControl>
C#代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
namespace INotifyPropertyChangedDemo
{
public partial class MainPage : UserControl
{
User user = User.CreateNewUser();
public MainPage()
{
InitializeComponent();
txtUserName.DataContext = user;
txtAge.DataContext = user;
//user.PropertyChanged += new PropertyChangedEventHandler(user_PropertyChanged);
}
//void user_PropertyChanged(object sender, PropertyChangedEventArgs e)
//{
// MessageBox.Show(e.PropertyName);
//}
private void btnHandle_Click(object sender, RoutedEventArgs e)
{
user.Age = 55;
}
}
public class User : INotifyPropertyChanged
{
private User()
{
UserName = "ruby";
Age = 23;
}
public static User CreateNewUser()
{
return new User();
}
#region Declare Field
private string userName;
public string UserName
{
get { return userName; }
set
{
if (value != userName)
{
userName = value;
OnPropertyChanged("UserName");
}
}
}
private int age;
public int Age
{
get { return age; }
set
{
if (value != age)
{
age = value;
OnPropertyChanged("Age");
}
}
}
#endregion
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
个人理解:在XAML中自动更新数据的功能原理是这样的。
- 首先它自动注册了一个事件。
user.PropertyChanged += new PropertyChangedEventHandler(user_PropertyChanged);
- 实现了这个事件的代码程序
void user_PropertyChanged(object sender, PropertyChangedEventArgs e) { }
- 在事件处理程序中根据传进来的字段名称,更改了Silverlight界面中的对应数据