【WPF标记扩展】RelativeSource与TemplateBinding

bing表达式相关的表达(例如:commandbing、TemplateBinding)都是订阅的意思。相当与winform编程中对事件的订阅。

MvvM模式中,view 元素绑定(订阅)viewmodel中的属性, 可以选择two 双向订阅,这样有任何一方变动都会通知对方。viewmodel其实就是内容提供者,给其他view订阅。

在xaml样式设计中,templateBing 表达式也是绑定的(订阅)的意思。这样模板发生变化就通知样式。

RelativeSource标记扩展

用法:<Binding RelativeSource="{RelativeSource PreviousData}"/>

{RelativeSource TemplatedParent}

绑定用法是一个关键技术,它解决了一个更大的概念,即控件的UI和控件的逻辑分离。这允许从模板定义内部绑定到被模板化的父模板(应用模板的运行时对象实例)。在这种情况下,TemplateBinding 标记扩展实际上是以下绑定表达式的缩写:{binding RelativeSource={RelativeSource TemplatedParent}}

TemplateBinding或{RelativeSource TemplatedParent}的用法都只在定义模板的XAML中使用,TemplatedParent表示表达式绑定到应用模板的元素。

{RelativeSource find祖先}

主要用于控件模板或可预测的自包含UI组合中,用于控件总是期望位于某个祖先类型的可视化树中的情况。例如,项控件的项可以使用find祖先用法绑定到其项控件父祖先的属性。或者,模板中作为控件组合一部分的元素可以使用find祖先绑定到相同组合结构中的父元素。
在XAML语法部分中显示的find祖先模式的对象元素语法中,第二个对象元素语法专门用于find祖先模式。FindAncestor模式需要一个祖先类型的值。您必须使用指向要查找的祖先类型的x:Type Markup Extension引用将祖先类型设置为属性。当在运行时处理绑定请求时,使用祖先类型值。
对于find祖先模式,当元素树中可能存在多于一个该类型的祖先时,可选属性祖先级别可以帮助消除对祖先查找的歧义。
有关如何使用find祖先模式的更多信息,请参阅RelativeSource。

{RelativeSource Self}

适用于这样的场景:一个实例的一个属性应该依赖于同一个实例的另一个属性的值,并且这两个属性之间不存在一般的依赖属性关系(比如强制)。尽管在一个对象上很少有两个值完全相同(而且类型完全相同)的属性,但您也可以将Converter参数应用到具有{RelativeSource Self}的绑定,并使用转换器在源类型和目标类型之间进行转换。{RelativeSource Self}的另一个场景是作为MultiDataTrigger的一部分。
例如,下面的XAML定义了一个Rectangle元素,无论为Width输入什么值,它总是一个正方形:

{RelativeSource PreviousData}

在数据模板中或者绑定使用集合作为数据源的情况下都很有用。您可以使用{RelativeSource PreviousData}来突出显示集合中相邻数据项之间的关系。一种相关的技术是在数据源中的当前项和以前的项之间建立一个MultiBinding,并在该绑定上使用一个转换器来确定两个项及其属性之间的差异。


在下面的例子中,项目模板中的第一个TextBlock显示当前的编号。第二个TextBlock绑定是一个MultiBinding,它名义上有两个binding成分:当前记录,和一个通过使用{RelativeSource PreviousData}故意使用前一个数据记录的绑定。然后,MultiBinding上的转换器计算差异并将其返回给绑定。

TemplateBinding 标记扩展

TemplateBinding 标记扩展实际上是以下绑定表达式的缩写:{Binding RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}

 TemplateBinding是为了某个特定场景优化出来的数据绑定(bing)版本--需要把ControlTemplate里面的某个Property绑定到应用该ControlTemplate的控件的对应Property上。

TemplateBinding是针对模板场景的一种优化形式,类似于用{Binding RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}构造的Binding。TemplateBinding始终是单向绑定,即使属性涉及默认为双向绑定。所涉及的两个属性都必须是依赖属性。为了实现与模板父对象的双向绑定,可以使用下面的绑定语句:{binding RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay, Path=MyDependencyProperty}。
RelativeSource是另一个标记扩展,有时与TemplateBinding一起使用,或者代替TemplateBinding,以便在模板中执行相对属性绑定。

 

TemplateBinding 用法:

在属性赋值中直接的用法:
<object property="{TemplateBinding targetProperty}" .../>
如:<Border x:Name="border" CornerRadius="5" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
    表示将应用该模板控件元素的Background 应用与 模板中Border元素的Background。            
在模板或样式中用Setter属性的用法:
<Setter Property="propertyName" Value="{TemplateBinding targetProperty}" .../>

TemplatedParent模式

  在其中应用 ControlTemplate 的控件是此绑定的源。这一点可用来在模板级别应用绑定中的验证错误信息。

<StackPanel Orientation="Vertical">
        <Button Width="150" Height="35" Margin="0 20 0 0" Content="TemplateBinding">
            <Button.Background>
                <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
                    <GradientStop Color="BlueViolet" Offset="0.0"></GradientStop>
                    <GradientStop Color="WhiteSmoke" Offset="0.5"></GradientStop>
                    <GradientStop Color="BlueViolet" Offset="1.0"></GradientStop>
                </LinearGradientBrush>
            </Button.Background>
            <Button.Template>
                <ControlTemplate>
                    <Border BorderThickness="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=BorderThickness}"
                            Background="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Background}">
                        <TextBlock Text="{TemplateBinding Button.Content}"></TextBlock>
                    </Border>
                </ControlTemplate>
            </Button.Template>
        </Button>

    </StackPanel>

 

posted @ 2022-08-05 04:15  小林野夫  阅读(946)  评论(0编辑  收藏  举报
原文链接:https://www.cnblogs.com/cdaniu/