原文: WPF元素綁定 資料綁定簡介:資料綁定是一種關系,該關系告訴WPF從源對象提取一些資訊,并用這些資訊設定目标對象的屬性。目标屬性是依賴項屬性。源對象可以是任何内容,從另一個WPF元素乃至ADO.NET資料對象(如DataTable)或自行建立出資料對象。綁定用的是Binding類的一個執行個體,用的名稱空間是:System.Windows.Data;
1、綁定表達式。
資料綁定表達式使用的是XAML标記擴充(是以具有花括号),用到的是System.Windows.Data.Bingding類的一個執行個體,是以綁定表達式以單詞Binding開頭,還需要兩個額外的屬性:Element屬性(源元素)和Path屬性(源元素中的屬性)。
基本文法是:{Binding ElementName=源元素 Path=源屬性}
2、将元素綁定到一起。
資料綁定最簡單的情形是,源對象是WPF元素且源屬性是依賴項屬性,依賴項屬性具有内置更改通知支援,當源對象中改變依賴屬性值時,會立即更新目标對象中的綁定屬性。
XAML代碼:
<Window x:Class="元素綁定.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<Slider Name="slider1" Minimum="0" Maximum="50"></Slider>
<!--通過标記擴充和Binding關鍵字進行綁定,
ElementName=slider1:綁定的源元素是Slider,
Path=Value:綁定的屬性是Slider的Value屬性。
-->
<TextBlock FontSize="{Binding ElementName=slider1, Path=Value}">Hello,World!</TextBlock>
</StackPanel>
</Window>
效果圖:

3、綁定錯誤。
WPF如果綁定失敗,不會引發異常來通知與資料綁定相關的問題,可以通過調試- - - - ->視窗- - - - ->輸出進行檢視。
4、綁定模式。
BindingMode常用枚舉值 | |
名稱 | 說明 |
OneWay | 當源屬性變化時更新目标屬性(目标屬性變化時,源屬性不會變化) |
TwoWay | 源屬性變化時更新目标屬性,目标屬性變化時更新源屬性。 |
OneTime | 最初根據源屬性設定目标屬性,其後所有的改變都會被忽略(直到調用BindingExpression.UpdateTarget()方法才會更新) |
OneWayToSource | 與OneWay類型類似,但方向相反,當目标屬性變化時更新源屬性,但目标屬性永遠不會被更新。 |
5、使用代碼建立綁定。
在XAML标記中使用Binding标記擴充來聲明綁定表達式的效率是最高的。當然,也可以使用代碼建立綁定。
<Window x:Class="元素綁定.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<Slider Name="slider1" Minimum="0" Maximum="50" ></Slider>
<TextBlock Name="textBox1">Hello,World!</TextBlock>
</StackPanel>
</Window>
背景代碼:
/// <summary>
/// MainWindow.xaml 的互動邏輯
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
//執行個體化Binding對象。
Binding binding = new Binding();
//設定綁定源對象。
binding.Source = slider1;
//設定綁定源屬性。
binding.Path = new PropertyPath("Value");
//設定綁定源的模式。
binding.Mode = BindingMode.TwoWay;
//為textBox1元素設定綁定(綁定需要兩個參數,一個是依賴屬性,另一個是綁定對象)。
textBox1.SetBinding(TextBox.FontSizeProperty, binding);
}
}
6、移除綁定。
可使用BindingOperation類的ClearBinding()靜态方法和ClearAllBindings()靜态方法移除綁定。
//移除綁定的對象。
BindingOperations.ClearAllBindings(textBox1);
//兩個參數,移除綁定的對象和移除綁定的依賴項屬性。
BindingOperations.ClearBinding(textBox1, TextBox.FontSizeProperty);
7、多綁定。
就是在一個元素上為多個屬性綁定。
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Slider Name="slider1" VerticalAlignment="Center" Minimum="10" Maximum="150"></Slider>
<TextBox Name="textbox1" Margin="20" Grid.Row="1"></TextBox>
<TextBlock Grid.Row="2" FontSize="{Binding ElementName=slider1,Path=Value}" Text="{Binding ElementName=textbox1,Path=Text}" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
</Grid>
效果圖:
8、綁定更新。
一般情況下,TextBox的綁定更新是失去焦點以後才會應用到元素上,如果把UpdateSourceTrigger設定為PropertyChange,就會實時更新了。UpdateSourceTrigger常用枚舉值如下。
UpdateSourceTrigger枚舉值 | |
PropertyChange | 當目标屬性發生變化時立即更新源 |
LostFocus | 當目标屬性發生變化且目标屬性丢失焦點時更新源 |
Explict | 除非調用BindingExpression.UpdateSource()方法,否則無法更新源(驗證情況下,使用這個,在觸發事件的過程調用BindingExpression.UpdateSource()方法)。 |
Default | 預設效果和大多數元素都是PropertyChange,但TextBox屬性的預設行為是LostFocus |
9、綁定延遲。
在極少數情況下,需要防止資料綁定觸發操作和修改源對象,至少在某一時間段是這樣的,這個時候可以使用Binding對象的Delay屬性,機關是毫秒。如Delay=5000,就是5秒後才更新。
10、綁定到非元素。
在資料驅動的應用程式中,更常見的情況是建立從不可見對象中提取資料的綁定表達式。唯一的要求是希望顯示的資訊必須存儲在公有屬性中,WPF資料綁定基礎結構不能擷取私有資訊或公有字段。當綁定到非元素對象時,可使用Source屬性、RelativeSource屬性、DataContent屬性。
10.1)、Source。
source:該屬性是指向源對象的引用(提供資料的對象),說白了就是為源資料指派的地方。
例子1:将Source屬性指向已經準備好的靜态對象。
<TextBlock Text="{Binding Source={x:Static SystemFonts.StatusFontFamily},Path=Source}" FontSize="20"></TextBlock>
這個綁定表達式擷取由靜态屬性屬性SystemFonts.StatusFontFamily提供的FontFamily對象,設定Binding.Source屬性時,需要借助靜态标記擴充,然後将Binding.Path屬性設定為FontFamily.Source屬性。該屬性給出了字型家族的名稱。
例子2:綁定到先前建立好的資源對象。
<!--定義資源-->
<Window.Resources>
<FontFamily x:Key="ResourceFamily">Hello,World</FontFamily>
</Window.Resources>
<!--引用資源-->
<TextBlock Text="{Binding Source={StaticResource ResourceFamily},Path=Source}"></TextBlock>
10.2)、RelativeSource。
RelativeSource:這是引用,使用RelativeSource對象指向源對象,RelativeSource是一種特殊工具,當編寫控件模闆以及資料模闆時是很友善的。Relative屬性可根據相對目标對象的關系指向源對象,例如可使用RelativeSource屬性将元素綁定到自身或其父元素(不知道在元素樹中從目前元素到綁定的父元素之間有多少代)。
RelativeSourceMode枚舉值 | |
Self | 表達式綁定到統一進制素的另一進制素上。 |
FindAncestor | 表達式綁定到父元素,WPF查找元素樹直至發現期望的父元素,為了指定父元素,還必須設定AncestorType屬性以訓示希望查找的父元素的類型,還可以使用AncestorLevel屬性略過發現的一定數量的特定元素。例如, 當在一棵樹中查找時,如果希望綁定到第三個ListBox類型的元素,應當設定:AncestorType={x:Type ListBoxItem};并且設定AncestorLevel=3,進而略過前兩個ListBoxItem元素,預設情況下AncestorLevel屬性 設定為1,找到第一個比對的元素時停止查找。 |
PreviousData | 表達式綁定到資料綁定清單的前一個資料項,在清單項中使用這種模式。 |
TemplateParent | 表達式綁定到應用模闆的元素。 |
例子:
<StackPanel>
<!--方式1、綁定到父元素上-->
<TextBlock Height="100">
<TextBlock.Text>
<Binding Path="Title"> <!--建立Binding對象和設定綁定路徑為Title-->
<Binding.RelativeSource>
<RelativeSource Mode="FindAncestor" AncestorType="{x:Type Window}"></RelativeSource> <!--設定綁定模式和父元素的類型-->
</Binding.RelativeSource>
</Binding>
</TextBlock.Text>
</TextBlock>
<!--方式2、綁定到父元素上-->
<TextBox Text="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"></TextBox>
<!--綁定到自身上面,綁定屬性為自身的高-->
<TextBox Height="50" Text="{Binding Path=Height, RelativeSource={RelativeSource Mode=Self}}"></TextBox>
</StackPanel>
10.3)、DataContent。
DataContent:如果沒有使用Source或RelativeSource屬性指定源,WPF就從目前元素開始在元素樹中向上查找,檢查每個元素的DataContext屬性,并使用第一個非空的DataContext屬性,當要将同一個對象的多個屬性綁定到不同的元素時,DataContext屬性是非常有用的,因為可以在更高的容器對象上設定DataContext屬性。
<!--定義一個靜态資源-->
<Window.Resources>
<FontFamily x:Key="SourceFamily" >Hello,World</FontFamily>
</Window.Resources>
<!--通過Source普通引用-->
<StackPanel>
<TextBlock Text="{Binding Source={StaticResource SourceFamily},Path=Source}"></TextBlock>
<TextBlock Text="{Binding Source={StaticResource SourceFamily},Path=Source}"></TextBlock>
<TextBlock Text="{Binding Source={StaticResource SourceFamily},Path=Source}"></TextBlock>
</StackPanel>
<!--通過DataContext形式-->
<StackPanel>
<TextBlock Text="{Binding Source={StaticResource SourceFamily},Path=Source}"></TextBlock>
<TextBlock Text="{Binding Source={StaticResource SourceFamily},Path=Source}"></TextBlock>
<TextBlock Text="{Binding Source={StaticResource SourceFamily},Path=Source}"></TextBlock>
</StackPanel>
<!--通過DataContext屬性進行綁定-->
<StackPanel DataContext="{StaticResource SourceFamily}">
<TextBlock Text="{Binding }"></TextBlock> <!--直接寫一個Binding綁定即可-->
<TextBlock Text="{Binding }"></TextBlock>
<TextBlock Text="{Binding Path = source}"></TextBlock>
</StackPanel>
End!