一、INotifyPropertyChanged 的基本概念
INotifyPropertyChanged 的作用:通知客戶端屬性值已經更改。詳細資訊見:INotifyPropertyChanged 介面(Microsoft)。實現介面如下圖:
二、優化 INotifyPropertyChanged 介面實現
優化後的 INotifyPropertyChanged 介面實現類如下所示:
1 class NofifyPropertyChanged : INotifyPropertyChanged
2 {
3 public event PropertyChangedEventHandler PropertyChanged;
4 protected void SetProperty<T>(ref T prop, T value, [CallerMemberName] string propertyName = null)
5 {
6 if (EqualityComparer<T>.Default.Equals(prop, value) == false)
7 {
8 prop = value;
9 OnPropertyChanged(propertyName);
10 }
11 }
12
13 public virtual void OnPropertyChanged(string propertyName)
14 {
15 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
16 }
17 }
例如與 UI 繫結的 ViewModel 如下所示:
class Window1VM : NofifyPropertyChanged
{
private string _name;
public string Name
{
get => _name;
set => SetProperty(ref _name, value);
}
}
三、ViewModel 與 UI 介面繫結
UI 介面如下圖所示:
XAML 繫結程式碼如下圖:
1 <Window x:Class="UI.Window1"
2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6 xmlns:local="clr-namespace:UI"
7 d:DataContext="{d:DesignInstance local:Window1VM}"
8 mc:Ignorable="d"
9 Title="Window1" Height="250" Width="300">
10 <StackPanel Margin="10" >
11 <TextBlock Text="Name Value(Read and Write):"></TextBlock>
12 <TextBox Margin="0,5,0,5" Height="50" VerticalContentAlignment="Center" BorderBrush="BlueViolet" BorderThickness="3" Text="{Binding Path=Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></TextBox>
13 <TextBlock Text="Name Value(Only Read):"></TextBlock>
14 <TextBox Margin="0,5,0,5" Height="50" VerticalContentAlignment="Center" BorderBrush="BlueViolet" BorderThickness="3" Text="{Binding Path=Name,Mode=OneWay}"></TextBox>
15 </StackPanel>
16 </Window>
在 Window1 介面的後置程式碼中初始化 ViewModel ,如下圖所示:
執行程式後,兩個文字框繫結的內容正常顯示,當我們改變第一個文字框內的內容時,第二個文字框的內容同步發生變化,這表示,Window1VM 的屬性 “Name” 和 Window1.xaml 中文字框的 “Text”屬性繫結成功!