在WPF中,为什么TemplateBinding不能在Binding中工作?

时间:2011-05-06 14:55:18

标签: wpf binding controltemplate propertychanged templatebinding

好的......这让我摸不着头脑。我有两个WPF控件 - 一个是用户控件,另一个是自定义控件。我们称他们为UserFoo和CustomFoo。在CustomFoo的控件模板中,我使用UserFoo的一个实例,这是一个命名的部分,所以我可以在应用模板后到达它。这很好。

现在UserFoo和CustomFoo都定义了Text属性(独立地,即不是使用AddOwner的共享DP。请不要......),这两个属性都被声明为......

public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
    "Text",
    typeof(string),
    typeof(UserFoo), // The other is CustomFoo
    new FrameworkPropertyMetadata(
        null,
        FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
        null,
        null,
        true,
        UpdateSourceTrigger.PropertyChanged
    )
);

特别注意模式设置为TwoWay,UpdateSourceTrigger设置为PropertyChanged,两者都是。

因此,在CustomFoo的样式模板中,我希望将CustomFoo的Text属性绑定到内部UserFoo的Text属性的源。通常,这很容易。你只需将UserFoo的文本属性设置为“{TemplateBinding Text}”,但由于某种原因,它只是一种方式(即从FreeFoo正确设置UserFoo,但不是相反),即使再次,两个DP都设置为双向!但是,当使用相对源绑定而不是模板绑定时,它工作得很好!嗯......哇??

// This one works
Text="{Binding Text, RelativeSource={RelativeSource AncestorType={local:CustomFoo}}, Mode=TwoWay}"

// As does this too...
Text="{Binding Text, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"

// But not this one!
Text="{TemplateBinding Text}"

那是什么给出的?我错过了什么?

2 个答案:

答案 0 :(得分:50)

在MSDN上发现此论坛帖子:http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/0bb3858c-30d6-4c3d-93bd-35ad0bb36bb4/

它说:

TemplateBinding是模板场景绑定的优化形式,类似于用

构造的绑定
{Binding RelativeSource={RelativeSource TemplatedParent}}.
  OP的注意事项:与文档中的内容相反,实际上应该是这样......

{Binding RelativeSource={RelativeSource TemplatedParent} Mode=OneWay}. 

我对文档提出了投诉,虽然他们确实添加了一个句子,现在说它们总是单向的,但代码示例仍然没有列出模式,但我想它总比没有好。)

TemplateBinding将数据从模板化父级转移到模板绑定的属性。如果需要以相反方向或双向传输数据,请使用TemplatedParent的RelativeSource创建一个绑定,并将Mode属性设置为OneWayToSource或TwoWay。

更多信息:http://msdn.microsoft.com/en-us/library/ms742882.aspx

看起来 Mode = OneWay 是使用TemplateBinding的“优化”之一

答案 1 :(得分:10)

TemplateBinding不支持双向绑定,只有Binding才支持。即使使用BindsTwoWayBeDefault选项,它也不支持双向绑定。

可以找到更多信息here,但总结一下:

  

但是,只能使用TemplateBinding   从一个方向传输数据:from   元素的模板化父级   使用TemplateBinding。如果你需要   以相反的方式传输数据   方向或两种方式,一个绑定   TemplatedParent的RelativeSource是   你唯一的选择。例如,   与TextBox或Slider的交互   在模板中只会改变一个   模板化父级的属性if   你使用双向绑定。