在WPF應用的開發過程中Binding是一個非常重要的部分。
在實際開發過程中Binding的不同種寫法達到的效果相同但事實是存在很大區別的。
這里將實際中碰到過的問題做下匯總記錄和理解。
1. 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 DataContext="abc"> <Label Content="{Binding}"></Label> <Label Content="{Binding RelativeSource={RelativeSource Self},Path=DataContext}"></Label> </StackPanel>
<StackPanel DataContext="abc"> <Label Content="{Binding}"></Label> <Label DataContext="def" Content="{Binding RelativeSource={RelativeSource Self},Path=DataContext}"></Label> </StackPanel>
2.在Template的Trigger中改變Template中某個樣式控件的屬性
<Style TargetType="{x:Type Button}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Button}"> <Border> <Label x:Name="PART_Label" Content="{TemplateBinding ContentA}" /> </Border> <ControlTemplate.Triggers> <Trigger Property="IsChecked" Value="True"> 注: <Setter TargetName="PART_Label" Property="Content" Value="{Binding Path=ContentB, RelativeSource={RelativeSource TemplatedParent}}" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
當然把注:的這句改成<Setter TargetName="PART_Label" Property="Content" Value="{Binding Path=ContentB, RelativeSource={RelativeSource AncestorType={x:Type Button}}}">效果一樣。
當一個Binding有明確的數據來源時可以通過為Source或ElementName賦值的辦法讓Binding與之關聯,有的時候由於不能確定Source的對象叫什么名字,但知道它與作為Binding目標的對象在UI布局上有相對關系,比如控件自己關聯自己的某個數據、關聯自己某級容器的數據,就要使用Binding的RelativeSource屬性。RelativeSource屬性的數據類型為RelativeSource類,通過這個類的幾個靜態或非靜態屬性可以控制它搜索相對數據源的方式。
我們來看一看Elementname,Source,RelativeSource 三種綁定的方式
1.ElementName顧名思義就是根據Ui元素的Name來進行綁定:
例子:
<Window x:Name="MainWindow"> <Grid> <Button Background=”{Binding ElementName=MainWindow, Path=Background}”/> </Grid> </Window> 效果等同於 <Window> <Grid> <Button Background=”{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window},Path=Background}”/> </Grid> </Window>
區別:
ElementName屬性用於引用一個UI對象的名稱,其的作用域在同一XAML文件內,不能引用另一XAML文件的某個Ui元素名。
2.Source屬性用於指定對象綁定路徑的引用。 其特點是:Source屬性通常用於綁定設置的對象時,是已知的。
<Window x:Name="MainWindow"> <Grid> <Button Background=”{Binding Source={StaticResource ButtonStyle}}”/> </Grid> </Window>
3.RelativeSource
在不確定綁定的Source時,但知道與綁定對象兩者相對關系時就需要使用RelativeSource,這也是RelativeSource 與ElementName和Source的最大區別。
RelativeSource 的三種典型用法:
/1.UI元素的一個屬性綁定在自身的另一個屬性上
<Label Background = {Binding Path=Forgroud, RelativeSource={RelativeSource Self}} />
/2.UI元素的一個屬性綁定在某個父元素的屬性上
<Grid> <Label Background = {Binding Path=Background, RelativeSource={RelativeSource AncestorType={x:Type Grid}}}/> </Grid>
/3.Template中的元素的屬性綁定在Template使用者元素的屬性上
{Binding Path=PathToProperty, RelativeSource={RelativeSource TemplatedParent}}
例子:

<Style TargetType="{x:Type local:NumericUpDown}"> <Setter Property="HorizontalAlignment" Value="Center"/> <Setter Property="VerticalAlignment" Value="Center"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:NumericUpDown}"> <Grid Margin="3"> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Border BorderThickness="1" BorderBrush="Gray" Margin="2" Grid.RowSpan="2" VerticalAlignment="Center" HorizontalAlignment="Stretch"> <TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Value}" Width="60" TextAlignment="Right" Padding="5"/> </Border> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>
利用TemplateBinding 綁定模板與原對象之間的屬性
{TemplateBinding Path=PathToProperty}
例子:
<ControlTemplate TargetType="{x:Type Button}" x:Key="buttonTemp"> <Border BorderThickness="3" Background="{TemplateBinding Foreground}"> <TextBlock Foreground="{TemplateBinding Background}"/> </Border> </ControlTemplate>
轉載時,請注明本文來源:www.cnblogs.com/tmywu