当目标是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
,则绑定成功:
如果我硬编码图像源路径,它也可以正常工作:
那么,为什么TemplateBinding
在ImageBrush
失败?
更新
通过演绎(并感谢克里斯的答案),可能的因素是:
-
ImageBrush
inheritance自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
解决问题。
从理论上讲,这是完全相同的约束……所以,谁知道呢? 无论什么有效。