这一节是对.NET2.0事件绑定技术的总结。
.NET事件绑定是基于Observer模式的,关于这部分见我的《CLR笔记10.事件》。在.NET2.0中,对Observer进行了一次包装,可以引用System.Component命名空间,实现INotifyPropertyChanged接口,可以获得事件PropertyChanged,以及PropertyChangedEventArgs。于是在这套体系下,事件机制事先搭建好了。
namespace System.ComponentModel
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
public delegate void PropertyChangedEventHandler(object sender, PropertyChangedEventArgs e);
![](/Images/OutliningIndicators/InBlock.gif)
public interface INotifyPropertyChanged
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
event PropertyChangedEventHandler PropertyChanged;
}
![](/Images/OutliningIndicators/InBlock.gif)
public class PropertyChangedEventArgs : EventArgs
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public PropertyChangedEventArgs(string propertyName);
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public virtual string PropertyName
{ get; }
}
}
下面看一个例子,这个例子将贯穿本章。
XAML部分:
<Window
>
<Grid>
![](https://www.cnblogs.com/Images/dot.gif)
<TextBlock
>Name:</TextBlock>
<TextBox x:Name="nameTextBox"
/>
<TextBlock
>Age:</TextBlock>
<TextBox x:Name="ageTextBox"
/>
<Button x:Name="birthdayButton"
>Birthday</Button>
</Grid>
</Window>
![](/Images/OutliningIndicators/None.gif)
后台代码部分:
public partial class Window1 : System.Windows.Window
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
Person person = new Person("Tom", 9);
![](/Images/OutliningIndicators/InBlock.gif)
public Window1()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
InitializeComponent();
![](/Images/OutliningIndicators/InBlock.gif)
this.nameTextBox.Text = person.Name;
this.ageTextBox.Text = person.Age.ToString();
![](/Images/OutliningIndicators/InBlock.gif)
// Watch for changes in the controls
this.nameTextBox.TextChanged += nameTextBox_TextChanged;
this.ageTextBox.TextChanged += ageTextBox_TextChanged;
![](/Images/OutliningIndicators/InBlock.gif)
person.PropertyChanged += person_PropertyChanged;
![](/Images/OutliningIndicators/InBlock.gif)
this.birthdayButton.Click += birthdayButton_Click;
}
![](/Images/OutliningIndicators/InBlock.gif)
void person_PropertyChanged(object sender, PropertyChangedEventArgs e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
switch (e.PropertyName)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
case "Name":
this.nameTextBox.Text = person.Name;
break;
![](/Images/OutliningIndicators/InBlock.gif)
case "Age":
this.ageTextBox.Text = person.Age.ToString();
break;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
void nameTextBox_TextChanged(object sender, TextChangedEventArgs e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
person.Name = nameTextBox.Text;
}
![](/Images/OutliningIndicators/InBlock.gif)
void ageTextBox_TextChanged(object sender, TextChangedEventArgs e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
int age = 0;
if (int.TryParse(ageTextBox.Text, out age))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
person.Age = age;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
private void birthdayButton_Click(Object sender, RoutedEventArgs e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
++person.Age;
![](/Images/OutliningIndicators/InBlock.gif)
MessageBox.Show(
string.Format(
"Happy Birthday, {0}, age {1}!",
person.Name,
person.Age),
"Birthday");
}
}
辅助类:
public class Person : INotifyPropertyChanged
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public Person()
{ }
public Person(string name, int age)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
this.name = name;
this.age = age;
}
![](/Images/OutliningIndicators/InBlock.gif)
string name;
public string Name
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return this.name; }
set
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
this.name = value;
OnPropertyChanged("Name");
}
}
![](/Images/OutliningIndicators/InBlock.gif)
int age;
public int Age
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return this.age; }
set
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
this.age = value;
OnPropertyChanged("Age");
}
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
INotifyPropertyChanged Members#region INotifyPropertyChanged Members
![](/Images/OutliningIndicators/InBlock.gif)
public event PropertyChangedEventHandler PropertyChanged;
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
protected void OnPropertyChanged(string propName)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (this.PropertyChanged != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
![](/Images/OutliningIndicators/InBlock.gif)
}
显示效果:
![](/images/cnblogs_com/jax/INotifyPropertyChanged.gif)