原文:RelativeSource 简述

RelativeSource实现标记扩展,以描述绑定源相对于绑定目标的位置。

<Binding>
<Binding.RelativeSource>
<RelativeSource Mode="modeEnumValue"/>
</Binding.RelativeSource>
</Binding>
- or
<Binding>
<Binding.RelativeSource>
<RelativeSource
Mode="FindAncestor"
AncestorType="{x:Type typeName}"
AncestorLevel="intLevel"
/>
</Binding.RelativeSource>
</Binding>
    // Summary:
// Describes the location of the binding source relative to the position of
// the binding target.
public enum RelativeSourceMode
{
// Summary:
// Allows you to bind the previous data item (not that control that contains
// the data item) in the list of data items being displayed.
PreviousData = ,
//
// Summary:
// Refers to the element to which the template (in which the data-bound element
// exists) is applied. This is similar to setting a System.Windows.TemplateBindingExtension
// and is only applicable if the System.Windows.Data.Binding is within a template.
TemplatedParent = ,
//
// Summary:
// Refers to the element on which you are setting the binding and allows you
// to bind one property of that element to another property on the same element.
Self = ,
//
// Summary:
// Refers to the ancestor in the parent chain of the data-bound element. You
// can use this to bind to an ancestor of a specific type or its subclasses.
// This is the mode you use if you want to specify System.Windows.Data.RelativeSource.AncestorType
// and/or System.Windows.Data.RelativeSource.AncestorLevel.
FindAncestor = ,
}

Xaml 示例

     <Window.Resources>
<ControlTemplate x:Key="template">
<Canvas>
<Canvas.RenderTransform>
<RotateTransform Angle="20"/>
</Canvas.RenderTransform>
<Ellipse Height="100" Width="150" Fill="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Background}"></Ellipse>
<ContentPresenter Margin="35" Content="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Content}"/>
</Canvas>
</ControlTemplate>
</Window.Resources>
<StackPanel>
<TextBlock>
<TextBlock.Text>
<Binding Path="Title">
<Binding.RelativeSource>
<RelativeSource Mode="FindAncestor" AncestorType="{x:Type Window}" />
</Binding.RelativeSource>
</Binding>
</TextBlock.Text>
</TextBlock>
<TextBlock Text="{Binding Path=Title,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}} }"></TextBlock>

<Button Template="{StaticResource template}" Background="AliceBlue">
<TextBlock FontSize="22">Click me</TextBlock>
</Button>
</StackPanel>

RelativeSource内部实现

using System;
using System.ComponentModel;
using System.Windows.Markup; namespace System.Windows.Data
{
public class RelativeSource : MarkupExtension, ISupportInitialize
{
public RelativeSource(); public RelativeSource(RelativeSourceMode mode); public RelativeSource(RelativeSourceMode mode, Type ancestorType, int ancestorLevel); public Type AncestorType { get; set; }

public RelativeSourceMode Mode { get; set; } public static RelativeSource PreviousData { get; } public static RelativeSource Self { get; } public static RelativeSource TemplatedParent { get; } public override object ProvideValue(IServiceProvider serviceProvider); ...
}
}
using System;
using System.ComponentModel;
using System.Windows.Markup;

namespace System.Windows.Data
{
/// <summary>Implements a markup extension that describes the location of the binding source relative to the position of the binding target.</summary>
[MarkupExtensionReturnType(typeof(RelativeSource))]
public class RelativeSource : MarkupExtension, ISupportInitialize
{
private RelativeSourceMode _mode;
private Type _ancestorType;
private int _ancestorLevel = -;
private static RelativeSource s_previousData;
private static RelativeSource s_templatedParent;
private static RelativeSource s_self;
/// <summary>Gets a static value that is used to return a <see cref="T:System.Windows.Data.RelativeSource" /> constructed for the <see cref="F:System.Windows.Data.RelativeSourceMode.PreviousData" /> mode.</summary>
/// <returns>A static <see cref="T:System.Windows.Data.RelativeSource" />.</returns>
public static RelativeSource PreviousData
{
get
{
if (RelativeSource.s_previousData == null)
{
RelativeSource.s_previousData = new RelativeSource(RelativeSourceMode.PreviousData);
}
return RelativeSource.s_previousData;
}
}
/// <summary>Gets a static value that is used to return a <see cref="T:System.Windows.Data.RelativeSource" /> constructed for the <see cref="F:System.Windows.Data.RelativeSourceMode.TemplatedParent" /> mode.</summary>
/// <returns>A static <see cref="T:System.Windows.Data.RelativeSource" />.</returns>
public static RelativeSource TemplatedParent
{
get
{
if (RelativeSource.s_templatedParent == null)
{
RelativeSource.s_templatedParent = new RelativeSource(RelativeSourceMode.TemplatedParent);
}
return RelativeSource.s_templatedParent;
}
}
/// <summary>Gets a static value that is used to return a <see cref="T:System.Windows.Data.RelativeSource" /> constructed for the <see cref="F:System.Windows.Data.RelativeSourceMode.Self" /> mode.</summary>
/// <returns>A static <see cref="T:System.Windows.Data.RelativeSource" />.</returns>
public static RelativeSource Self
{
get
{
if (RelativeSource.s_self == null)
{
RelativeSource.s_self = new RelativeSource(RelativeSourceMode.Self);
}
return RelativeSource.s_self;
}
}
/// <summary>Gets or sets a <see cref="T:System.Windows.Data.RelativeSourceMode" /> value that describes the location of the binding source relative to the position of the binding target.</summary>
/// <returns>One of the <see cref="T:System.Windows.Data.RelativeSourceMode" /> values. The default value is null.</returns>
/// <exception cref="T:System.InvalidOperationException">This property is immutable after initialization. Instead of changing the <see cref="P:System.Windows.Data.RelativeSource.Mode" /> on this instance, create a new <see cref="T:System.Windows.Data.RelativeSource" /> or use a different static instance.</exception>
[ConstructorArgument("mode")]
public RelativeSourceMode Mode
{
get
{
return this._mode;
}
set
{
if (this.IsUninitialized)
{
this.InitializeMode(value);
return;
}
if (value != this._mode)
{
throw new InvalidOperationException(SR.Get("RelativeSourceModeIsImmutable"));
}
}
}
/// <summary>Gets or sets the type of ancestor to look for.</summary>
/// <returns>The type of ancestor. The default value is null.</returns>
/// <exception cref="T:System.InvalidOperationException">The <see cref="T:System.Windows.Data.RelativeSource" /> is not in the <see cref="F:System.Windows.Data.RelativeSourceMode.FindAncestor" /> mode.</exception>
public Type AncestorType
{
get
{
return this._ancestorType;
}
set
{
if (this.IsUninitialized)
{
this.AncestorLevel = ;
}
if (this._mode != RelativeSourceMode.FindAncestor)
{
if (value != null)
{
throw new InvalidOperationException(SR.Get("RelativeSourceNotInFindAncestorMode"));
}
}
else
{
this._ancestorType = value;
}
}
}
/// <summary>Gets or sets the level of ancestor to look for, in <see cref="F:System.Windows.Data.RelativeSourceMode.FindAncestor" /> mode. Use 1 to indicate the one nearest to the binding target element.</summary>
/// <returns>The ancestor level. Use 1 to indicate the one nearest to the binding target element.</returns>
public int AncestorLevel
{
get
{
return this._ancestorLevel;
}
set
{
if (this._mode != RelativeSourceMode.FindAncestor)
{
if (value != )
{
throw new InvalidOperationException(SR.Get("RelativeSourceNotInFindAncestorMode"));
}
}
else
{
if (value < )
{
throw new ArgumentOutOfRangeException(SR.Get("RelativeSourceInvalidAncestorLevel"));
}
this._ancestorLevel = value;
}
}
}
private bool IsUninitialized
{
get
{
return this._ancestorLevel == -;
}
}
/// <summary>Initializes a new instance of the <see cref="T:System.Windows.Data.RelativeSource" /> class.</summary>
public RelativeSource()
{
this._mode = RelativeSourceMode.FindAncestor;
}
/// <summary>Initializes a new instance of the <see cref="T:System.Windows.Data.RelativeSource" /> class with an initial mode.</summary>
/// <param name="mode">One of the <see cref="T:System.Windows.Data.RelativeSourceMode" /> values.</param>
public RelativeSource(RelativeSourceMode mode)
{
this.InitializeMode(mode);
}
/// <summary>Initializes a new instance of the <see cref="T:System.Windows.Data.RelativeSource" /> class with an initial mode and additional tree-walking qualifiers for finding the desired relative source.</summary>
/// <param name="mode">One of the <see cref="T:System.Windows.Data.RelativeSourceMode" /> values. For this signature to be relevant, this should be <see cref="F:System.Windows.Data.RelativeSourceMode.FindAncestor" />.</param>
/// <param name="ancestorType">The <see cref="T:System.Type" /> of ancestor to look for.</param>
/// <param name="ancestorLevel">The ordinal position of the desired ancestor among all ancestors of the given type. </param>
public RelativeSource(RelativeSourceMode mode, Type ancestorType, int ancestorLevel)
{
this.InitializeMode(mode);
this.AncestorType = ancestorType;
this.AncestorLevel = ancestorLevel;
}
/// <summary>This member supports the Windows Presentation Foundation (WPF) infrastructure and is not intended to be used directly from your code.</summary>
void ISupportInitialize.BeginInit()
{
}

///<summary>This member supports the Windows Presentation Foundation (WPF) infrastructure and is not intended to be used directly from your code.</summary>
void ISupportInitialize.EndInit()
{
if (this.IsUninitialized)
{
throw new InvalidOperationException(SR.Get("RelativeSourceNeedsMode"));
}
if (this._mode == RelativeSourceMode.FindAncestor && this.AncestorType == null)
{
throw new InvalidOperationException(SR.Get("RelativeSourceNeedsAncestorType"));
}
}

/// <summary>Indicates whether the <see cref="P:System.Windows.Data.RelativeSource.AncestorType" /> property should be persisted.</summary>
/// <returns>true if the property value has changed from its default; otherwise, false.</returns>
public bool ShouldSerializeAncestorType()
{
return this._mode == RelativeSourceMode.FindAncestor;
}

/// <summary>Indicates whether the <see cref="P:System.Windows.Data.RelativeSource.AncestorLevel" /> property should be persisted.</summary>
/// <returns>true if the property value has changed from its default; otherwise, false.</returns>
public bool ShouldSerializeAncestorLevel()
{
return this._mode == RelativeSourceMode.FindAncestor;
}

/// <summary>Returns an object that should be set as the value on the target object's property for this markup extension. For <see cref="T:System.Windows.Data.RelativeSource" />, this is another <see cref="T:System.Windows.Data.RelativeSource" />, using the appropriate source for the specified mode. </summary>
/// <returns>Another <see cref="T:System.Windows.Data.RelativeSource" />.</returns>
/// <param name="serviceProvider">An object that can provide services for the markup extension. In this implementation, this parameter can be null.</param>
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (this._mode == RelativeSourceMode.PreviousData)
{
return RelativeSource.PreviousData;
}
if (this._mode == RelativeSourceMode.Self)
{
return RelativeSource.Self;
}
if (this._mode == RelativeSourceMode.TemplatedParent)
{
return RelativeSource.TemplatedParent;
}
return this;
}
private void InitializeMode(RelativeSourceMode mode)
{
if (mode == RelativeSourceMode.FindAncestor)
{
this._ancestorLevel = ;
this._mode = mode;
return;
}
if (mode == RelativeSourceMode.PreviousData || mode == RelativeSourceMode.Self || mode == RelativeSourceMode.TemplatedParent)
{
this._ancestorLevel = ;
this._mode = mode;
return;
}
throw new ArgumentException(SR.Get("RelativeSourceModeInvalid"), "mode");
}
}
}

RelativeSource 简述的更多相关文章

  1. Windows Presentation Foundation (WPF)中的命令(Commands)简述

    原文:Windows Presentation Foundation (WPF)中的命令(Commands)简述 ------------------------------------------- ...

  2. 简述 OAuth 2.0 的运作流程

    本文将以用户使用 github 登录网站留言为例,简述 OAuth 2.0 的运作流程. 假如我有一个网站,你是我网站上的访客,看了文章想留言表示「朕已阅」,留言时发现有这个网站的帐号才能够留言,此时 ...

  3. JavaScript单线程和浏览器事件循环简述

    JavaScript单线程 在上篇博客<Promise的前世今生和妙用技巧>的开篇中,我们曾简述了JavaScript的单线程机制和浏览器的事件模型.应很多网友的回复,在这篇文章中将继续展 ...

  4. Design Patterns Simplified - Part 3 (Simple Factory)【设计模式简述--第三部分(简单工厂)】

    原文链接:http://www.c-sharpcorner.com/UploadFile/19b1bd/design-patterns-simplified-part3-factory/ Design ...

  5. Android网络定位服务定制简述

    Android 添加高德或百度网络定位服务 Android的网络定位服务以第三方的APK方式提供服务,由于在国内Android原生自带的com.google.android.gms服务几乎处于不可用状 ...

  6. 《Entity Framework 6 Recipes》翻译系列 (1) -----第一章 开始使用实体框架之历史和框架简述

    微软的Entity Framework 受到越来越多人的关注和使用,Entity Framework7.0版本也即将发行.虽然已经开源,可遗憾的是,国内没有关于它的书籍,更不用说好书了,可能是因为EF ...

  7. 简述ASP.NET MVC原理

    1.为什么ASP.NET需要MVC? 因为随着网站的的数量级越来越大,原始的网站方式,这里指的是WebForm,在运行速度和维护性方面,以及代码量上面,越来越难以满足日益庞大的网站维护成本.代码的重构 ...

  8. Design Patterns Simplified - Part 2 (Singleton)【设计模式简述--第二部分(单例模式)】

    原文链接: http://www.c-sharpcorner.com/UploadFile/19b1bd/design-patterns-simplified-part-2-singleton/ De ...

  9. 【翻译】设计模式学习系列1---【Design Patterns Simplified: Part 1【设计模式简述:第一部分】】

    原文链接:http://www.c-sharpcorner.com/UploadFile/19b1bd/design-patterns-simplified-part1/ Design Pattern ...

随机推荐

  1. mysql中的触发器和事务的操作

    触发器 语法 创建触发器: CREATE TRIGGER trigger_name trigger_time trigger_event ON tbl_name FOR EACH ROW trigge ...

  2. SDE 空间表操作

    1. 创建空间表(包含st_geometry属性字段) CREATE TABLE sensitive_areas (area_id integer, name varchar(128), area_s ...

  3. [CSS Flex] Justify-content

    justify content contol how element inside flex box align, it can be "right / end", or &quo ...

  4. java 线程排查问题流程

    1. 通过top命令查看当前系统CPU使用情况,定位CPU使用率超过100%的进程ID:2. 通过ps aux | grep PID命令进一步确定具体的线程信息:3. 通过ps -mp pid -o ...

  5. KVC设置系统自带属性,不管是不是私有的属性

    KVC   可以设置系统自带属性,不管是不是私有的属性:    1,   2,  

  6. 【BZOJ 1022】 [SHOI2008]小约翰的游戏John

    [题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1022 [题意] [题解] 和这题类似http://blog.csdn.net/harl ...

  7. mysql半同步复制实现

    mysql半同步复制和异步复制的区别如上述架构图所看到的:在mysql异步复制的情况下.Mysql Master Server将自己的Binary Log通过复制线程传输出去以后,Mysql Mast ...

  8. POJ 2728 - 最小比例生成树

    传送门 题目大意 有n个村庄,每个村庄都有一个(x, y)坐标和z海拔,定义两个村庄间的dist为坐标的距离,cost为海拔差的绝对值,求图的一颗生成树,使得\(\frac{\sum cost}{\s ...

  9. maven Java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet

    如果你可以确认你的maven Dependencies中已经导入了如下的jar包,那么你就要检查下Deployment Assembly 选中项目 alt+enter,然后查看maven依赖有没有被添 ...

  10. windows 系统本地做mysql 主从同步,最后面解决主从同步库名不一致,表结构一致

    原文:windows 系统本地做mysql 主从同步,最后面解决主从同步库名不一致,表结构一致 mysql主从同步的好处以及原理       之前看到很多新闻说某某的服务器奔溃,磁盘碎了,导致数据丢失 ...