簡介
WPf提供了一個簡單而又強大的方式來自動更新業務層和使用者介面之間的資料,這鐘機制叫做資料繫結。每次當業務層的資料改變時,它都會自動更新使用者介面,反過來也一樣。這就是WPF在傳遞給使用者介面時候首選的方法。
資料繫結可以是單向的(資源-->目標或者目標-->資源)也可以是雙向的(資源<-->目標)。
要綁定的資源屬性可以是一個普通等CLR屬性,也可以是相依性屬性。但是綁定的目標屬性必須是一個相依性屬性。
為了讓綁定更好的工作,綁定的雙方都必須提供一個改變通知以便在一方改變的情況下更新另一方。普通的CLR屬性可以通過實現INotifyPropertyChanged介面的PropertyChanged方法來處理。相依性屬性則是通過中繼資料屬性的PropertyChanged的回調來處理的。
資料繫結在XAML中通常使用{Binding}擴充標籤來完成。下面例子簡單的展示了一個文字框和標籤的資料繫結,標籤裡的直會根據文字框的輸入而改變的哦。
<StackPanel>
<TextBox x:Name="txtInput" />
<Label Content="{Binding Text, ElementName=txtInput,
UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
資料內容(DataContext)
每一個由FrameworkElement衍生出來的WPF控制項都有DataContext屬性。這個屬性可以給其設定一個可見的資料對象。一旦不能準確地為其綁定一個資源,可以給其預設一個DataContext。
DataContext可以為它的子控制項傳承它的值。所以可以在上層的版面配置容器中設定一個DataContext,那麼它的所有子控制項就都繼承了它的值。這點在你想綁定一個i資料對象的多個屬性時是非常有用的。
代碼
<StackPanel DataContext="{StaticResource myCustomer}">
<TextBox Text="{Binding FirstName}"/>
<TextBox Text="{Binding LastName}"/>
<TextBox Text="{Binding Street}"/>
<TextBox Text="{Binding City}"/>
</StackPanel>
數值轉換
如果你想把兩個不同類型的屬性綁定在一起時,就不得不使用數值轉換了。一個數值轉換器可以將值從源類型轉換到目標類型並能成功返回。WPF雖然已經有一些數值轉換取,但是大多數情況下你還是需要執行IValueConverter介面來寫出自己的轉換器。
一個經典的例子就是給控制項的Visibililty屬性綁定一個Bool值。但visibility屬性是一個包含Visble,Collapsed和Hidden的枚舉類型,所以你需要一個如下的轉換器:
代碼
<StackPanel>
<StackPanel.Resources>
<BooleanToVisibilityConverter x:Key="boolToVis" />
</StackPanel.Resources>
<CheckBox x:Name="chkShowDetails" Content="Show Details" />
<StackPanel x:Name="detailsPanel"
Visibility="{Binding IsChecked, ElementName=chkShowDetails,
Converter={StaticResource boolToVis}}">
</StackPanel>
</StackPanel>
下面的例子展示了一個將Bool類型轉換為visibilty的簡單轉換器。提示:這個轉換器已經包含在.NetFramework裡了。
代碼
public class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
CultureInfo culture)
{
if (value is Boolean)
{
return ((bool)value) ? Visibility.Visible : Visibility.Collapsed;
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter,
CultureInfo culture)
{
throw new NotImplementedException();
}
}