当目标是ImageBrush.ImageSource时,TemplateBinding失败

为什么在这种特定情况下, TemplateBinding似乎失败了?

拿一个基本的扩展按钮:

 public class IconButton : Button { public ImageSource Icon { get { return (ImageSource)GetValue(IconProperty); } set { SetValue(IconProperty, value); } } public static readonly DependencyProperty ImageProperty = DependencyProperty.Register("Icon", typeof(ImageSource), typeof(IconButton), new PropertyMetadata(null)); public IconButton() { DefaultStyleKey = typeof(IconButton); } } 

控件模板使用OpacityMask显示图标:

                  

这无声地失败 – 控件显示为实心矩形。 如果我使用常规图像而不是ImageBrush ,则绑定成功:

       

如果我硬编码图像源路径,它也可以正常工作:

           

那么,为什么TemplateBindingImageBrush失败?


更新

通过演绎(并感谢克里斯的答案),可能的因素是:

  • ImageBrushinheritance自DependencyObject而不是FrameworkElement
  • TemplateBinding不像普通绑定那样支持隐式类型转换(即string-to-ImageSource)

我仍然没有看到点如何连接,但……

有趣的是,我设法从你的例子中复制了这种行为,虽然我不能完全确定,但我想我可能会理解发生了什么。

基于这个问题的答案: WPF TemplateBinding vs RelativeSource TemplatedParent似乎虽然两种方法实现了几乎相同的东西,但它们在一些关键行为上有所不同。 Miroslav Nedyalkov提到的最相关的一个 –

“TemplateBindings不允许进行值转换。它们不允许您传递转换器,也不会自动将int转换为字符串(例如,绑定是正常的)。”

我猜想在第二种情况下,绑定将使用内置的WPF转换器将绑定的string / URI转换为ImageSource (指定ImageSource时的通常行为 – 这就是为什么通常不需要指定绑定转换器)。

在第一种情况下,您将无法获得默认值转换,因此您将看不到掩码。 有趣的是,如果指定了转换器,它是否会起作用。

编辑:看起来ImageBrush可能会有一些额外的复杂因素没有inheritance自FrameworkElement : 将ImageBrush绑定到带有DependencyProperty的模板

这是一个解决方法。 奇怪的是,使用RelativeSource TemplatedParent绑定而不是TemplateBinding解决问题。

  

从理论上讲,这是完全相同的约束……所以,谁知道呢? 无论什么有效。