本文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