WPF TemplateBinding vs RelativeSource TemplatedParent

这两个绑定有什么区别

<ControlTemplate TargetType="{x:Type Button}"> <Border BorderBrush="{TemplateBinding Property=Background}"> <ContentPresenter /> </Border> </ControlTemplate> 

 <ControlTemplate TargetType="{x:Type Button}"> <Border BorderBrush="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}"> <ContentPresenter /> </Border> </ControlTemplate> 

TemplateBinding是不完全相同的事情。 MSDN文档通常由需要testing单音节软件特性的软件特性的人撰写,因此细微之处不太正确。

在编译时根据控件模板中指定的types来评估TemplateBindings。 这允许编译模板更快的实例化。 只要摸索模板绑定的名称,你会看到编译器会标记它。

绑定标记在运行时parsing。 虽然执行速度较慢,但​​绑定将parsing在模板声明的types上不可见的属性名称。 由于速度较慢,我将指出它的相对性,因为绑定操作占用的应用程序的CPU很less。 如果你在高速爆炸控制模板,你可能会注意到它。

作为练习的问题,尽可能使用TemplateBinding,但不要害怕Binding。

TemplateBinding – 比使用常规绑定更有限制

  • 比绑定更高效,但function更less
  • 只在ControlTemplate的可视化树内工作
  • 不适用于Freezables上的属性
  • 在ControlTemplate的触发器中不起作用
  • 提供设置属性的快捷方式(而不是详细),例如{TemplateBinding targetProperty}

常规绑定 – 不具有TemplateBinding的上述限制

  • 尊重父项属性
  • 重置目标值以清除任何显式设置的值
  • 例如:<Ellipse Fill =“{Binding RelativeSource = {RelativeSource TemplatedParent},Path = Background}”/>

还有一件事 – TemplateBindings不允许值转换。 他们不允许你通过一个转换器,并不会自动将int转换为string,例如(这是正常的绑定)。

TemplateBinding是与TemplatedParent绑定的简写,但它不公开Binding类的所有function,例如,您无法从TemplateBinding控制Binding.Mode。

RelativeSource TemplatedParent

此模式可以将给定的ControlTemplate属性绑定到ControlTemplate所应用的控件的属性。 为了更好地理解这个问题,下面是一个例子

 <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> <Canvas Name="Parent0"> <Button Margin="50" Template="{StaticResource template}" Height="0" Canvas.Left="0" Canvas.Top="0" Width="0"> <TextBlock FontSize="22">Click me</TextBlock> </Button> </Canvas> 

如果我想将给定控件的属性应用于其控件模板,那么我可以使用TemplatedParent模式。 这个标记扩展也是类似的,它是TemplateBinding,它是第一个的简写,但是TemplateBinding是在编译时在TemplatedParent的对比度下计算的,而TemplatedParent是在第一次运行时间之后被评估的。 正如你可以在下图所示,背景和内容是从button内部应用到控制模板。

我认为TemplateBinding不支持Freezabletypes(其中包括画笔对象)。 解决问题。 可以使用TemplatedParent

它们以类似的方式使用,但它们有一些差异。 这里是TemplateBinding文档的链接: http : //msdn.microsoft.com/en-us/library/ms742882.aspx