RelativeSource 是一个标记扩展,扩展描述相对于绑定目标位置的绑定源位置。
RelSEO靠我ativeSource 作用是改变绑定指向的源,默认使用绑定的源是对应的DataContext对象中的属性,如果想要绑定源为其他元素,比如自身、其他父级控件、其他ViewModel,就需要用RelatSEO靠我iveSource 进行标记。它表示在绑定表达式中引用另一个元素的属性。它使开发人员可以根据元素的位置和类型来查找绑定源。
RelativeSource属性有四种模式:
FindAncestor:查找指定类型的父元素,和 AncestorType 或 AncestorLevel 一起使用SEO靠我。PreviousData:使用数据提供程序中的前一个数据项。Self:使用当前元素。TemplatedParent:查找元素的模板父级。绑定控件本身的属性
示例:
实现正方形控件SEO靠我(宽和高相等),通过RelativeSource 实现,使用Self将Width绑定到Height上。
Width="{Binding RelativeSource={RelativeSource SeSEO靠我lf}, Path=Height}"//或者 Width="{Binding RelativeSource={RelativeSource Mode=Self}, Path=HeighSEO靠我t}"控件的Xaml代码:
<ButtonWidth="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Height}"Height="SEO靠我100"Margin="40,67,0,0"HorizontalAlignment="Left"VerticalAlignment="Top"Content="Button"/>效果:
只需要修改HeiSEO靠我ght值,Width就会跟着变化
绑定控件父元素及更上一级的元素,使用Mode=FindAncestor和AncestorType 、 AncestorLevel配合实现。
如下几种定义效果是相同的
RelativeSoSEO靠我urce={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType=Grid} RelativeSource={SEO靠我RelativeSource AncestorLevel=1, AncestorType=Grid} RelativeSource={RelativeSource AncestorTySEO靠我pe=Grid}示例:
通过设置一个Button的Width和不同父级布局控件的宽度绑定来演示FindAncestor模式
当前界面代码:
<Windowx:Class="WpfRelativeSourceSEO靠我Example.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://SEO靠我schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmSEO靠我lns:local="clr-namespace:WpfRelativeSourceExample"xmlns:mc="http://schemas.openxmlformats.org/markupSEO靠我-compatibility/2006"Title="MainWindow"Width="800"Height="450"mc:Ignorable="d"><Grid><StackPanel BackSEO靠我ground="LightGray"><GridWidth="768"Height="380"Margin="0,27,0,0"HorizontalAlignment="Left"BackgroundSEO靠我="Gray"><GridWidth="396"Height="344"Margin="0,36,0,0"HorizontalAlignment="Left"VerticalAlignment="ToSEO靠我p"Background="Linen"><Canvas Margin="0,53,173,0" Background="DarkCyan" ><ButtonCanvas.Top="56"HeightSEO靠我="100"HorizontalAlignment="Center"VerticalAlignment="Top"Content="Button" /></Canvas></Grid></Grid><SEO靠我/StackPanel></Grid> </Window>将Button的Width设置和Canvas一样,增加下面的绑定
Width="{Binding Width, RelativeSEO靠我Source={RelativeSource Mode=FindAncestor, AncestorType=Canvas}}"此时并未生效
因为规则4中说明对应Canvas未定义,对应的Width属性SEO靠我,所有无法生效,只要对应Canvas设置了Width属性,RelativeSource就生效了。
然后依次跟上面两级的Grid的绑定
第一级:
<ButtonCanvas.Top="56"Width="{BSEO靠我inding Width, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}}"Height="100"HoriSEO靠我zontalAlignment="Center"VerticalAlignment="Top"Content="Button" />//等效 <ButtonCanvas.Top="56SEO靠我"Width="{Binding Width, RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorTSEO靠我ype=Grid}}"Height="100"HorizontalAlignment="Center"VerticalAlignment="Top"Content="Button" />第二级:
<BuSEO靠我ttonCanvas.Top="56"Width="{Binding Width, RelativeSource={RelativeSource Mode=FindAncestor, AncestorSEO靠我Level=2, AncestorType=Grid}}"Height="100"HorizontalAlignment="Center"VerticalAlignment="Top"Content=SEO靠我"Button" />TemplatedParent模式主要用在重写或者定义控件模板Template中,用于将模板中的属性和控件本身的属性绑定,类似TemplateBSEO靠我inding,可以对TemplateBinding进行扩展,利用Converter实现一些TemplateBinding不支持的属性绑定
示例:
<ButtonMargin="49,60,0,0"PaddSEO靠我ing="10"HorizontalAlignment="Left"VerticalAlignment="Top"Content="Button"><Button.Style><Style TargeSEO靠我tType="Button"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="Button"><BordeSEO靠我r Background="{TemplateBinding Background}"><ContentPresenter Margin="{Binding Path=Padding, RelativSEO靠我eSource={RelativeSource TemplatedParent}}" Content="{TemplateBinding Content}" /></Border></ControlTSEO靠我emplate></Setter.Value></Setter></Style></Button.Style></Button>PreviousData可以在数据绑定表达式SEO靠我中使用前一个数据项。通常在ItemsControl中使用,用于根据前一个项的属性计算当前项的属性。PreviousData只能在ItemsControl或其派生类中使用。
使用场景,暂无示例
使用SEO靠我RelativeSource改变绑定的ViewModel对象。在嵌套的ViewModel中,命令一定要写在对应的VIewModel(或者Model)中才能实现绑定,这时可以通过RelativeSourSEO靠我ce绑定到其父级的ViewModel中的命令上。
比如在DataGrid列中有按钮事件,就必须对应的命令需要写在对应的Model中增加命令
正常下一个DataGird(在用户控件UserManageUC.SEO靠我xaml中)
<DataGridWidth="605"Height="341"Margin="59,74,0,0"HorizontalAlignment="Left"VerticalAlignment=SEO靠我"Top"AutoGenerateColumns="False"ItemsSource="{Binding Users}"><DataGrid.Columns><DataGridTextColumn SEO靠我Binding="{Binding Id}" Header="序号" /><DataGridTextColumn Binding="{Binding Name}" Header="姓名" /><DatSEO靠我aGridTextColumn Binding="{Binding Age}" Header="年龄" /><DataGridTemplateColumn Header="操作"><DataGridTSEO靠我emplateColumn.CellTemplate><DataTemplate><StackPanel Orientation="Horizontal"><Button Command="{BindSEO靠我ing ModifyCmd}" Content="修改" /><Button Content="删除" /></StackPanel></DataTemplate></DataGridTemplateSEO靠我Column.CellTemplate></DataGridTemplateColumn></DataGrid.Columns></DataGrid>对应的数据模型UserModel
public clSEO靠我ass UserModel{public int Id { get; set; }public string Name { get; set; }public int Age { get; set; SEO靠我}public CommandBase ModifyCmd{get{return new CommandBase(o =>{MessageBox.Show($"UserModel Modify:{NaSEO靠我me}");});}}} }在对应的ViewModel创建集合并初始化
public class UserManageUCViewModel : ViewModelBase{publicSEO靠我 ObservableCollection<UserModel> Users{ get; set; }public UserManageUCViewModel(){Users= new ObservaSEO靠我bleCollection<UserModel>();Users.Add(new UserModel() { Id=1,Name="张三",Age=11});Users.Add(new UserModSEO靠我el() { Id=2,Name="李四",Age=22});}}此时效果,正常使用命令
在UserManageUCViewModel 上添加命令
public ComSEO靠我mandBase ModifyCmd {get{return new CommandBase(o =>{var user=o as UserModel;MessageBox.Show(SEO靠我$"UserManageUCViewModel Modify:{user.Name}");});} }改变按钮Command的绑定,使用RelativeSource的FindAncesSEO靠我tor模式RelativeSource={RelativeSource AncestorType=local:UserManageUC}帮绑定对象改为UserManageUC用户控件,然后目标改为DaSEO靠我taContext.ModifyCmd,然后增加CommandParameter,将该行绑定的数据作为命令参数传入
<ButtonCommand="{Binding DataContext.ModifySEO靠我Cmd, RelativeSource={RelativeSource AncestorType=local:UserManageUC}}"CommandParameter="{Binding}"CoSEO靠我ntent="修改" />效果:
网站备案号:浙ICP备17034767号-2