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

Mar*_*eIV 41 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
    )
);
Run Code Online (Sandbox Code Playgroud)

请特别注意,模式设置为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}"
Run Code Online (Sandbox Code Playgroud)

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

Mat*_*est 53

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

它说:

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

{Binding RelativeSource={RelativeSource TemplatedParent}}
Run Code Online (Sandbox Code Playgroud)

OP的注意事项:与文档中的内容相反,实际上,它应该是......

{Binding RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

  • 我同意-令人沮丧的是,您必须在其论坛上对某个问题的某些答复中找到它。他们应该更新MSDN页面以反映这一点。 (2认同)

Cod*_*ked 11

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

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

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