本文github:https://github.com/kiwiwin/silverlight-demo,文件夹:domain-service-duplex-by-auto-refresh-demo
RelativeSource可以用来指定binding的source和binding的target之间的位置关系。
RelativeSource的三种模式:1.Self模式
目标元素应用作此绑定的源。当要将元素的一个属性绑定到同一元素的另一个属性时,上述这点很有用。
<object property="{Binding RelativeSource={RelativeSource Self} ...}" .../>
2.TemplatedParent模式
在其中应用 ControlTemplate 的控件是此绑定的源。这一点可用来在模板级别应用绑定中的验证错误信息。
<object property="{Binding RelativeSource={RelativeSource TemplatedParent} ...}" .../>
3.FindAncestor模式
无论何时使用FindAncestor模式,通常会指定AncestorType的值。如果树遍历中存在多义性,可指定一个AncestorLevel。
<object property="{Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=typeNameString, AncestorLevel=levelInt} ...}" .../>
备注:
在绑定中,Source、RelativeSource 和 ElementName是相互排斥的。如果已设置这些属性中的一种,则在绑定中设置其他两种属性的任何一种(通过 XAML 或代码)将导致异常。
例:
我们期望datagrid中的template column中的Button随着State的改变而改变是否为Enabled,同时对比datagrid外的一个Test Button在binding时与datagrid中的button的区别
MainPage.xaml
<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" x:Class="binding_to_relative_source.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <Grid x:Name="LayoutRoot" Background="White"> <Button Content="Change" Click="ChangeButton_OnClick" Width="300" Height="30" VerticalAlignment="Top"/> <Button Content="Test" IsEnabled="{Binding State}" Width="300" Height="30" VerticalAlignment="Top" Margin="0,40,0,0"/> <sdk:DataGrid Name="kiwiDataGrid" AutoGenerateColumns="False" Width="300" Height="200" VerticalAlignment="Top" Margin="0,80,0,0"> <sdk:DataGrid.Columns> <sdk:DataGridTextColumn Binding="{Binding Name}" Width="150"/> <sdk:DataGridTemplateColumn> <sdk:DataGridTemplateColumn.CellTemplate> <DataTemplate> <Button Content="Dummy Button" IsEnabled="{Binding State, RelativeSource={RelativeSource AncestorType=UserControl}}"/> </DataTemplate> </sdk:DataGridTemplateColumn.CellTemplate> </sdk:DataGridTemplateColumn> </sdk:DataGrid.Columns> </sdk:DataGrid> </Grid> </UserControl>
MainPage.xaml.cs
public partial class MainPage : UserControl, INotifyPropertyChanged { public bool State { get; set; } public event PropertyChangedEventHandler PropertyChanged; public void NotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } public MainPage() { InitializeComponent(); DataContext = this; var kiwis = new List<Kiwi>(); kiwis.Add(new Kiwi {Name = "a"}); kiwis.Add(new Kiwi {Name = "b"}); kiwis.Add(new Kiwi {Name = "c"}); kiwis.Add(new Kiwi {Name = "d"}); kiwiDataGrid.ItemsSource = kiwis; State = true; } private void ChangeButton_OnClick(object sender, RoutedEventArgs e) { State = !State; NotifyPropertyChanged("State"); } } public class Kiwi { public String Name { get; set; } }
运行效果:
Enabled
Disable