原文: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. JS和CSS压缩部署,提高访问效率

    一直想把项目中的js和css压缩下,今天终于搞定了. 先说说几个注意的问题,目标影响着你对应的解决办法:1.压缩后的文件,是否要直接覆盖旧的文件2. 单个压缩文件重命名,还是整个目录换个名字,同时文件 ...

  2. 【42.86%】【codeforces 742D】Arpa's weak amphitheater and Mehrdad's valuable Hoses

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  3. 从多路搜索树到 B-树

    1. 什么是 B 树 B 树是为磁盘或其他直接存取的辅助存储设备而设计的一种平衡二叉树: B 树类似于红黑树,但它们在降低磁盘 I/O 操作数方面要更好一点, 许多数据库系统使用 B 树或者 B 树的 ...

  4. 浏览器jsp、html之间的关系

    浏览器html.jsp之间的关系 1.HTML能直接通过浏览器打开,而JSP仅仅能公布到Tomcatserver才干打开. 2.HTML中不能嵌套Java代码,而JSP中能够嵌套Java代码: 3.H ...

  5. 数据库迁移框架Flyway介绍

    官方文档 https://flywaydb.org/getstarted/firststeps/api[https://flywaydb.org/getstarted/firststeps/api] ...

  6. amazeui中的js插件有哪些(详解功能)

    amazeui中的js插件有哪些(详解功能) 一.总结 一句话总结: 二.amazeui中的js插件有哪些 1.UI 增强 警告框Alert 按钮交互Button 折叠面板Collapse 下拉组件D ...

  7. hadoop 3.x 服役 | 退役数据节点

    在服役前要配置好新增主机的环境变量,ssh等信息,个人环境介绍 hadoop002(namenode),hadoop003(resourcemanager),hadoop004(secondaryna ...

  8. 在navicat上设置定时计划执行存储过程

    原文 应用情景: 有一个存储过程,需要每天定时执行一次.所以在navicat上使用事件处理,当然还有其他的方法,这只是一种.作为参考 1.事件定义填写 2.事件计划设置 3.保存 点击上方保存即可 常 ...

  9. Java类、实例的初始化顺序

    今晚是阿里巴巴 2013 校园招聘的杭州站笔试.下午匆忙看了两张历年试卷,去现场打了瓶酱油. 题目总体考察点偏基础,倒数第二题(Java 附加题)比较有趣,考察了 Java 初始化机制的细节,在此摘录 ...

  10. 发布与订阅SQLServer

    SQLServer 中发布与订阅 在对数据库做迁移的时候,会有很多方法,用存储过程,job,也可以用开源工具lettle,那么今天这些天变接触到了一种新的方法,就是SqlServer中自带的发布与订阅 ...