好的......这让我摸不着头脑。我有两个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}"
那是什么给出的?我错过了什么?
答案 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 你使用双向绑定。