WPF里分三種Binding:Binding, PriorityBinding,MultiBinding,這三種Binding的基類都是BindingBase,而BindingBase又繼承於MarkupExtension
1.Binding 中 綁定到其他控件 ElementName
Binding 綁定是 模式設置 Mode
2. source = {binding} 和source = {binding RelativeSource={RelativeSource self},Path=DataContext}效果相同
理解:{binding} 不設定明確的綁定的source,這樣binding就去從本控件類為開始根據可視樹的層次結構自下而上查找不為空的Datacontext屬性的值。
{binding RelativeSource={RelativeSource self},Path=DataContext}中RelativeSource self的含義為綁定的source為控件自身,這樣binding 就綁定了自身控件的Datacontext。
<StackPanel Orientation="Vertical" DataContext="上海世博會"> <Border BorderThickness="2" BorderBrush="BlueViolet"> <TextBlock Text="{Binding}"></TextBlock> </Border> <Border BorderThickness="2" BorderBrush="BlueViolet"> <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=DataContext}"></TextBlock> </Border> </StackPanel>
RelativeSource 可以用來指定binding的source和binding的target之間的位置關系。
RelativeSource的四種模式:
1.RelativeSource Mode=Self 模式:
目標元素應用作此綁定的源。當要將元素的一個屬性綁定到同一元素的另一個屬性時。
<StackPanel Orientation="Vertical" DataContext="上海世博會" Name="stackPanel"> <Border BorderThickness="2" BorderBrush="BlueViolet"> <TextBlock Name="綁定自己的屬性" Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Name}"></TextBlock> </Border> </StackPanel>
效果 但是把 Xmal 改成如下時 !此時Path=Name 並不會去容器的Name 屬性 尋找 StackPanel Name=“stackPanel”
<TextBlock Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Name}"></TextBlock>
此時為空
但是:當Path=DataContext 就會出現另一個效果
<StackPanel Orientation="Vertical" DataContext="上海世博會" Name="stackPanel"> <Border BorderThickness="2" BorderBrush="BlueViolet"> <TextBlock Name="綁定自己的屬性" Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=DataContext}" DataContext="北京歡迎你"></TextBlock> </Border> </StackPanel>
把 DataContext="北京歡迎你" 。刪除后 Path=DataContext 就會向上尋找 DataContext 只到找到為止。
<TextBlock Name="綁定自己的屬性" Text="{Binding RelativeSource={RelativeSource Mode=Self}, Path=DataContext}"></TextBlock>1.Self模式
2.PreviousData 模式:
允許您綁定所顯示數據項列表中以前的數據項(不是包含數據項的控件)。源碼:
<Window x:Class="WPFBindingDemo.RelativeSourceWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WPFBindingDemo" xmlns:collection="clr-namespace:System.Collections;assembly=mscorlib" xmlns:sys="clr-namespace:System;assembly=mscorlib" Title="RelativeSourceWindow" Height="300" Width="300"> <Window.Resources> <collection:ArrayList x:Key="cillectionkey"> <sys:String>上海</sys:String> <sys:String>北京</sys:String> <sys:String>天津</sys:String> <sys:String>南京</sys:String> </collection:ArrayList> </Window.Resources> <StackPanel Orientation="Vertical"> <ListBox ItemsSource="{StaticResource ResourceKey=cillectionkey}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding}"></TextBlock> <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=PreviousData}}" Margin="15 0 0 0"></TextBlock> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </StackPanel> </Window>
效果圖:
3.TemplatedParent模式
在其中應用 ControlTemplate 的控件是此綁定的源。這一點可用來在模板級別應用綁定中的驗證錯誤信息。
<StackPanel Orientation="Vertical"> <Button Width="150" Height="35" Margin="0 20 0 0" Content="TemplateBinding"> <Button.Background> <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5"> <GradientStop Color="BlueViolet" Offset="0.0"></GradientStop> <GradientStop Color="WhiteSmoke" Offset="0.5"></GradientStop> <GradientStop Color="BlueViolet" Offset="1.0"></GradientStop> </LinearGradientBrush> </Button.Background> <Button.Template> <ControlTemplate> <Border BorderThickness="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=BorderThickness}" Background="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Background}"> <TextBlock Text="{TemplateBinding Button.Content}"></TextBlock> </Border> </ControlTemplate> </Button.Template> </Button> </StackPanel>
效果圖:
TemplateBinding和Binding的區別
TemplateBinding是為了某個特定場景優化出來的數據綁定版本--需要把ControlTemplate里面的某個Property綁定到應用該ControlTemplate的控件的對應Property上。
TemplateBinding 用法:
在屬性賦值中直接的用法:
<object property="{TemplateBinding targetProperty}" .../>
在模板或樣式中用Setter屬性的用法:
<Setter Property="propertyName" Value="{TemplateBinding targetProperty}" .../>
兩者區別:
1. Binding比TemplateBinding更加靈活強大,但是開銷也更大。TemplateBinding在使用場景有限制,但是效率較高。Template非常類似{Binding RelativeSource={RelativeSource TemplatedParent}}構造的Binding。
2. TemplateBinding同樣允許我們定義Converter和ConverterParameter,在一定程度上加強了TemplateBinding的應用功能和范圍.
3. 最重要的區別:TemplateBinding僅僅支持單向的數據綁定,從應用Template的控件到Template(from templated control to template)。如果我們需要反向或者雙向的綁定,唯一的選擇就是應用Binding和RelativeSource。
使用時如何選擇:
如果我們需要一個單向的綁定,使數據從應用template的控件(templated parent)到template,我們就該使用高效而簡單的TemplateBinding,其他情況下都使用Binding。
4.FindAncestor模式
FindAncestor:引用數據綁定元素父鏈中的上級。 您可以使用它綁定到特定類型或其子類的上級。 如果您要指定 AncestorType 和/或 AncestorLevel,可以使用此模式
AncestorType 獲取或設置要查找的上級節點的類型。如果未顯式設置 Mode 屬性,那么設置 AncestorType 或 AncestorLevel 屬性將把 Mode 屬性值隱式鎖定為 FindAncestor。
<StackPanel Orientation="Vertical" Margin="0 20 0 0"> <Button Background="BlanchedAlmond"> <StackPanel> <Button Margin="20 0 0 0" HorizontalAlignment="Left" Background="RoyalBlue"> <StackPanel> <Button Margin="{Binding Path=Margin, RelativeSource={RelativeSource AncestorType=Button, Mode=FindAncestor}}" Content="上海世博會"></Button> <Button Content="北京奧運會"></Button> </StackPanel> </Button> </StackPanel> </Button> </StackPanel>
效果圖:
綁定二 xaml 源碼
<StackPanel Orientation="Vertical" Margin="0 20 0 0"> <Button Background="BlanchedAlmond"><!--AncestorLevel=2--> <StackPanel> <Button Margin="20 0 0 0" HorizontalAlignment="Left" Background="RoyalBlue"><!--AncestorLevel=1--> <StackPanel> <Button Margin="{Binding Path=Margin, RelativeSource={RelativeSource AncestorType=Button, Mode=FindAncestor}}" Content="上海世博會"></Button> <Button Content="北京奧運會" Background="{Binding Path=Background, RelativeSource={RelativeSource AncestorType={x:Type Button},
AncestorLevel=1, Mode=FindAncestor}}"> </Button> </StackPanel> </Button> </StackPanel> </Button> </StackPanel>
效果圖: AncestorLevel=1 修改成 AncestorLevel=2 背景設為
<Button Content="北京奧運會" Background="{Binding Path=Background, RelativeSource={RelativeSource AncestorType={x:Type Button}, AncestorLevel=2, Mode=FindAncestor}}"></Button>
效果圖: