原文: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. ios开发手势处理之手势识别二

    #import "ViewController.h" @interface ViewController ()<UIGestureRecognizerDelegate> ...

  2. [NPM] Add comments to your npm scripts

    The need for comments in your package.json file becomes desirable the more and more npm scripts you ...

  3. Net程序调试

    Net程序调试 前言 作为一个.net开发工程师,不管是在写桌面程序.服务程序或web程序,在开发阶段,我们必须非常熟悉vs的动态调试技能,当然web程序可能还需要调试前端的脚本或样式,这不在本文的讨 ...

  4. 使用Spring Tool Suite (STS)新的工作空间无需再配置

    在你的新的工作空间中找到比如 F:\java-wokespace\你的新的工作空间名称\.metadata\.plugins\org.eclipse.core.runtime\.settings 找到 ...

  5. 第六章:任务执行——Java并发编程实战

    任务:通常是一些抽象的且离散的工作单元.大多数并发应用程序都是围绕"任务执行"来构造的,把程序的工作分给多个任务,可以简化程序的组织结构便于维护 一.在线程中执行任务 任务的独立性 ...

  6. javascript中window对象 部分操作

    <!--引用javascript外部脚本--> <script src="ss.js"></script> <script> //警 ...

  7. DirectX11学习笔记

    一.假定每种颜色的原始点是不同,表面的这样的原始颜色将被指定为每种颜色用线性内插值传授,这个被称为高洛德着色(Gouraud Shading).也称为平滑阴影: 二.三维图元:Direct3D中.使用 ...

  8. Mapreduce 订单分组案例

    程序执行流程如下: map()-->getPartition()分区--->write()(序列化,每一行都顺序执行这三个方法)--->readFields()---->com ...

  9. Node.js,一生所爱

    下午参加了<云品秀--前端前沿>,用友云平台前端架构师郭永峰(站着的那位)讲得很棒,而我最关注的就是Node了.最后我问了他关于独立开发,后端选择Node还是别的语言.他讲了很多,说自己在 ...

  10. 【87.65%】【codeforces 731A】Night at the Museum

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