在 WPF 中,为什么 TemplateBinding 不能像 Binding 一样工作?
好吧……这让我摸不着头脑。我有两个 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}”,但由于某种原因,它只能以一种方式进行(即 UserFoo 是从 CustomFoo 正确设置的,但反之则不然),尽管同样,两个 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}"
那么什么给出呢?我缺少什么?
Ok... this is leaving me scratching my head. I have two WPF controls--one's a user control and the other's a custom control. Let's call them UserFoo and CustomFoo. In the control template for CustomFoo, I use an instance of UserFoo which is a named part so I can get to it after the template is applied. That works fine.
Now both UserFoo and CustomFoo have a Text
property defined on them (independently, i.e. not a shared DP using AddOwner. Don't ask...) that are both declared like this...
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
)
);
Notice specifically that the mode is set to TwoWay and the UpdateSourceTrigger is set to PropertyChanged, again for both.
So in the style template for CustomFoo, I want to bind CustomFoo's Text property as the source to the internal UserFoo's Text property. Normally, this is easy. You just set UserFoo's text property to "{TemplateBinding Text}" but for some reason it's only going one way (i.e. UserFoo is properly set from CustomFoo, but not the reverse), even though again, both DPs are set for two-way! However, when using a relative source binding instead of a template binding, it works great! Um... wha??
// 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}"
So what gives? What am I missing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 MSDN 上找到此论坛帖子: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/0bb3858c-30d6-4c3d-93bd-35ad0bb36bb4/
它说:
A TemplateBinding是针对模板场景的 Binding 的优化形式,类似于用
我对文档提出了投诉,虽然他们确实添加了一句话,但现在指出它们总是单向的,代码示例仍然没有列出模式,但我想这总比没有好。)
TemplateBinding 将数据从模板化父级传输到模板绑定的属性。如果需要以相反方向或双向传输数据,请使用 TemplatedParent 的relativesource 创建一个 Binding,并将 Mode 属性设置为 OneWayToSource 或 TwoWay。
更多信息请参见:http://msdn.microsoft.com/en-us/library/ ms742882.aspx
看起来Mode=OneWay是使用TemplateBinding的“优化”之一
Found this forum post on MSDN: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/0bb3858c-30d6-4c3d-93bd-35ad0bb36bb4/
It says this:
A TemplateBinding is an optimized form of a Binding for template scenarios, analogous to a Binding constructed with
I filed a complaint against the docs, and while they did add a sentence now stating they are always one-way, the code example still doesn't list the mode, but I guess it's better than nothing.)
The TemplateBinding transfers data from the templated parent to the property that is template bound. If you need to transfer data in the opposite direction or both ways, create a Binding with RelativeSource of TemplatedParent with the Mode property set to OneWayToSource or TwoWay.
More in: http://msdn.microsoft.com/en-us/library/ms742882.aspx
Looks like Mode=OneWay is one of the "Optimizations" of using a TemplateBinding
TemplateBinding 不支持双向绑定,只有 Binding 可以支持。即使使用 BindsTwoWayBeDefault 选项,它也不支持双向绑定。
更多信息可以在此处找到,但总结一下:
TemplateBinding does not support two-way binding, only Binding does that. Even with your BindsTwoWayBeDefault option, it won't support two-way binding.
More info can be found here, but to summarize: