我正在尝试创建一个特殊按钮,根据系统中的Foreground颜色为图像着色。解决方案似乎是使用图像作为不透明蒙版来获取颜色,当我像这样直接设置图像时它可以工作:
<Grid>
<Rectangle x:Name="ImageForeground" Height="48" Width="48"
Fill="{StaticResource PhoneForegroundBrush}" >
<Rectangle.OpacityMask>
<ImageBrush Stretch="Fill" ImageSource="/icons/play.png"/>
</Rectangle.OpacityMask>
</Rectangle>
</Grid>
但是,一旦我尝试使用DependencyProperty为图像精简版创建模板:
public static readonly DependencyProperty ImageProperty =
DependencyProperty.Register("Image", typeof(ImageSource),
typeof(RButton), null);
然后在XAML中这样:
<Grid>
<Rectangle x:Name="ImageForeground" Height="48" Width="48"
Fill="{TemplateBinding Foreground}" >
<Rectangle.OpacityMask>
<ImageBrush Stretch="Fill" ImageSource="{TemplateBinding Image}"/>
</Rectangle.OpacityMask>
</Rectangle>
</Grid>
我收到错误说:
object of type 'System.Windows.CustomDependencyProperty'
cannot be converted to type 'System.Windows.DependencyProperty'
ImageProperty没问题,因为我测试将它绑定到图像而不是像这样
<Image Source="{TemplateBinding Image}" Width="48" Height="48" />
有什么想法吗?我的预感说明了我如何定义我的DependecyProperty,但我不知道如何继续前进。
答案 0 :(得分:6)
ImageBrush不从FrameworkElement继承,因此它不能是TemplateBound或Data Bound。
答案 1 :(得分:3)
我尝试在基于您给出的XAML的测试项目中复制您的问题,并且不得不承认我没有遇到您描述的问题。如果你能提供RButton
的代码和一些关于如何使用控件的上下文,我可能会有更多的运气(或缺少!)。
今天发布了一篇很棒的博文All about Dependency Properties in Silverlight for WP7,您可能会发现它很有用。
更新:我刚刚阅读了完全匹配的article,它完全解释了问题并提供了解决方案。基本上,ImageBrush
不是FrameworkElement
,因此您无法使用TemplateBinding
。
答案 2 :(得分:3)
我将它标记为答案虽然不是完整的答案。为了让它全部工作,我不得不做一些调整,因为我无法在TemplateBinding中使用转换器,无论如何叹息......以下代码与Derek指出的article中的转换器一起为我解决了这个问题。
所以要将我的Image DependencyProperty绑定为我的模板中的图像画笔,我必须这样做...
<Grid>
<Grid.Resources>
<controls:ImageBrushConverter x:Key="brushConverter"/>
</Grid.Resources>
<Rectangle
x:Name="ImageForeground"
Height="48"
Width="48"
Fill="{TemplateBinding Foreground}"
DataContext="{TemplateBinding Image}"
OpacityMask="{Binding Converter={StaticResource brushConverter}}">
</Rectangle>
</Grid>
不明显,但它确实有效,这对我来说已经解决了很多。谢谢你的帮助
答案 3 :(得分:2)
您可以使用RelativeSource TemplatedParent
绑定而不是TemplateBinding。这基本上是一回事,但它适用于那些模板绑定没有的奇怪情况。
<ImageBrush
ImageSource="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Image}" />
答案 4 :(得分:0)
另一种方法,但不需要转换器
<Grid>
<Rectangle x:Name="ImageForeground" DataContext="{TemplateBinding Image}" Height="48" Width="48"
Fill="{TemplateBinding Foreground}" >
<Rectangle.OpacityMask>
<ImageBrush Stretch="Fill" ImageSource="{Binding DataContext , RelativeSource={RelativeSource AncestorType=Rectangle}}"/>
</Rectangle.OpacityMask>
</Rectangle>
//或
<Rectangle DataContext="{TemplateBinding IconVisual}" x:Name="Icon" RadiusX="2" RadiusY="2" StrokeThickness="1" Margin="{TemplateBinding Padding}" Fill="{TemplateBinding Foreground}" Stroke="{TemplateBinding Foreground}" >
<Rectangle.OpacityMask>
<VisualBrush Visual="{Binding DataContext , RelativeSource={RelativeSource AncestorType=Rectangle}}" Stretch="Uniform" />
</Rectangle.OpacityMask>
</Rectangle>
答案 5 :(得分:0)
或者,如果您是控件的作者,那么OnApplyTemplate,在模板中找到可视画笔并设置其值。
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
VisualBrush oVBrushBack = (VisualBrush)this.Template.FindName("rectVisual", this);
oVBrushBack.Visual = this.IconVisual;
}