【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>