当客户端绑定一个数据模型以后,数据模型变化以后可以自动通知客户端更新界面显示,这就是INotifyPropertyChanged接口要做的工作。INotifyPropertyChanged 接口用于向客户端(通常是执行绑定的客户端)发出某一属性值已更改的通知。例如,考虑一个带有名为 FirstName 属性的 Person 对象。 若要提供一般性属性更改通知,则 Person 类型实现INotifyPropertyChanged 接口并在 FirstName 更改时引发 PropertyChanged 事件。 若要在将客户端与数据源进行绑定时发出更改通知,则绑定类型应具有下列功能:实现INotifyPropertyChanged接口。
当绑定的属性改变时,它可以通知客户端,并进行界面数据更新。而我们不用写很多复杂的代码来更新界面数据,这样可以做到方法简洁而清晰,松耦合和让方法变得更通用。可用的地方太多了:例如上传进度,实时后台数据变更等地方。
(另:对于集合Model:INotifyCollectionChanged结接口会有ObservableCollection自动实现(见上一篇))
一个简单的例子:(下面的例子中TextBlock绑定了DataContext的ModelName,点击按钮以后model更新,TextBlock会自动更新)
Model:
1
public
class
MyModel : INotifyPropertyChanged
2
{
3
public
event
PropertyChangedEventHandler PropertyChanged;
4
5
public
int
ModelID {
get
;
set
; }
6
7
private
string
_ModelName;
8
public
string
ModelName
9
{
10
get
{
return
_ModelName; }
11
set
12
{
13
_ModelName
=
value;
14
15
if
(PropertyChanged
!=
null
)
16
{
17
PropertyChanged(
this
,
new
PropertyChangedEventArgs(
"
ModelName
"
));
18
}
19
}
20
}
21
}
Silverlight页面:
1
<
Grid
x:Name
="LayoutRoot"
Background
="White"
>
2
<
TextBlock
Height
="46"
HorizontalAlignment
="Left"
Margin
="187,51,0,0"
Name
="textBlock1"
Text
="
{Binding ModelName}
"
VerticalAlignment
="Top"
Width
="94"
/>
3
<
Button
Content
="update"
Height
="39"
HorizontalAlignment
="Left"
Margin
="187,120,0,0"
Name
="button1"
VerticalAlignment
="Top"
Width
="106"
Click
="button1_Click"
/>
4
</
Grid
>
页面代码:
1
public
MyView()
2
{
3
InitializeComponent();
4
5
MyModel m1
=
new
MyModel() { ModelID
=
1
, ModelName
=
"
abc
"
};
6
7
this
.DataContext
=
m1;
8
}
9
10
private
void
button1_Click(
object
sender, RoutedEventArgs e)
11
{
12
(
this
.DataContext
as
MyModel).ModelName
=
"
abc_changed
"
;
13
}
甚至还有一个VS2010插件来完成这个工作:NotifyPropertyWeaver
ViewModel也可以实现INotifyPropertyChanged接口,很简单:
XAML绑定集合:
1
<
DataGrid
ItemsSource
="
{Binding Path=LineItems}
"
/>
ViewModel代码:
1
public
class
OrderViewModel : INotifyPropertyChanged
2
{
3
public
OrderViewModel( IOrderService orderService )
4
{
5
this
.LineItems
=
new
ObservableCollection
<
OrderLineItem
>
(
6
orderService.GetLineItemList() );
7
}
8
9
public
ObservableCollection
<
OrderLineItem
>
LineItems {
get
;
private
set
; }
10
}