RelativeSource 简述

简介: 原文:RelativeSource 简述RelativeSource实现标记扩展,以描述绑定源相对于绑定目标的位置。 - or // Summary: // Describes th...
原文: 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 = 0,
        //
        // 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 = 1,
        //
        // 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 = 2,
        //
        // 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 = 3,
    }

 

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 = -1; 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 = 1; } 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 != 0) { throw new InvalidOperationException(SR.Get("RelativeSourceNotInFindAncestorMode")); } } else { if (value < 1) { throw new ArgumentOutOfRangeException(SR.Get("RelativeSourceInvalidAncestorLevel")); } this._ancestorLevel = value; } } } private bool IsUninitialized { get { return this._ancestorLevel == -1; } } /// <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 = 1; this._mode = mode; return; } if (mode == RelativeSourceMode.PreviousData || mode == RelativeSourceMode.Self || mode == RelativeSourceMode.TemplatedParent) { this._ancestorLevel = 0; this._mode = mode; return; } throw new ArgumentException(SR.Get("RelativeSourceModeInvalid"), "mode"); } } }

 

目录
相关文章
|
5月前
|
开发者
简述函数和框架的区别
简述函数和框架的区别
35 1
|
6月前
|
存储 安全 编译器
【C++】—— 简述C++11新特性
【C++】—— 简述C++11新特性
|
6月前
|
缓存
KVCache原理简述
KVCache原理简述
190 0
|
5月前
|
开发者
简述库和框架的区别
简述库和框架的区别
53 2
|
6月前
|
存储 监控 算法
JVM工作原理与实战(四十一):ShenandoahGC原理
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了ShenandoahGC、ShenandoahGC 1.0版本、ShenandoahGC 2.0版本、ShenandoahGC执行流程等内容。
57 0
|
6月前
|
Oracle Java 关系型数据库
Java历史简述及程序运行机制简述
Java起源于1991年Sun公司James Gosling领导的Green项目,最初命名为Oak,后因爪哇岛咖啡更名为Java。1995年正式发布,2009年Sun被Oracle收购。Java程序运行包括:开发源代码、编译成字节码、JVM翻译为平台兼容的机器码执行。
|
网络协议 Java
JavaRPC原理与实现简介
远程过程调用(Remote Procedure Call,简称RPC)是一种计算机通信协议,它允许在不同的进程之间进行通信,就像在本地调用一样。JavaRPC是基于Java语言实现的一种RPC框架,旨在简化分布式系统的开发和管理。
159 0
简述for in 和 for of 的区别
1、推荐在循环对象属性的时候使用 for...in,在遍历数组的时候的时候使用 for...of 2、for...in 循环出的是 key,for...of 循环出的是 value
145 0
简述for in 和 for of 的区别
|
Linux 开发工具 git
Blktrace原理简介及使用
Blktrace简介 Blktrace是一个用户态的工具,用来收集磁盘IO信息中当IO进行到块设备层(block层,所以叫blk trace)时的详细信息(如IO请求提交,入队,合并,完成等等一些列的信息)。
1585 0
个人简述
以下是我的个人简述