49

好吧...这让我摸不着头脑。我有两个 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 的 text 属性设置为“{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}"

那么给了什么?我错过了什么?

4

2 回答 2

71

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

它是这样说的:

TemplateBinding 是针对模板场景的 Binding 的优化形式,类似于使用构造的 Binding

{Binding RelativeSource={RelativeSource TemplatedParent}}

OP 的注释:与文档中所说的相反,实际上,它应该是这个......

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

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

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

更多内容:http: //msdn.microsoft.com/en-us/library/ms742882.aspx

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

于 2011-05-06T15:06:42.013 回答
11

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

更多信息可以在这里找到,但总结一下:

但是,TemplateBinding 只能在一个方向传输数据:从模板化的父级到具有 TemplateBinding 的元素。如果您需要以相反的方向或双向传输数据,与 TemplatedParent 的 RelativeSource 的绑定是您唯一的选择。例如,如果您使用双向绑定,则与模板中的 TextBox 或 Slider 的交互只会更改模板化父级上的属性。

于 2011-05-06T15:07:15.720 回答