Bind ImageBrush to a template using DependencyProperty

I am trying to create a special button that colors an image based on the Foreground color from the system. Apparently, the solution is to use the image as an opacity mask to get the color, and it works when I set the image directly as follows:

<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>

But as soon as I try the template using DependencyProperty for the lite image, do the following:

public static readonly DependencyProperty ImageProperty  =
  DependencyProperty.Register("Image", typeof(ImageSource), 
                              typeof(RButton), null);  

And then in XAML, like this:

<Grid>
  <Rectangle x:Name="ImageForeground" Height="48" Width="48" 
    Fill="{TemplateBinding Foreground}" >
    <Rectangle.OpacityMask>
      <ImageBrush Stretch="Fill" ImageSource="{TemplateBinding Image}"/>
    </Rectangle.OpacityMask>
  </Rectangle>
</Grid>

I get an error message:

object of type 'System.Windows.CustomDependencyProperty' 
  cannot be converted to type 'System.Windows.DependencyProperty'

ImageProperty is fine as I tested image binding instead

<Image Source="{TemplateBinding Image}" Width="48" Height="48" />

Any ideas? My hunch is about how I define my DependecyProperty, but I don't know how to move forward.

+2
6

ImageBrush FrameworkElement, TemplateBound Data Bound.

+6

XAML, , , , . RButton , , ( !).

Silverlight WP7, , .

UPDATE: . , ImageBrush FrameworkElement, TemplateBinding .

+3

, . , , TemplateBinding, ... . , , .

, 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

You can use binding RelativeSource TemplatedParentinstead of TemplateBinding. This is basically the same, but it will work in those odd cases where TemplateBinding does not.

<ImageBrush
    ImageSource="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Image}" />
+2
source

Another approach, but without a converter

<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>

//Or

<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>
0
source

Or, if you are the author of the control, then OnApplyTemplate, find the visual brush in the template and set its value.

public override void OnApplyTemplate()
{
    base.OnApplyTemplate();

    VisualBrush oVBrushBack = (VisualBrush)this.Template.FindName("rectVisual", this);

    oVBrushBack.Visual = this.IconVisual;
}
0
source

Source: https://habr.com/ru/post/1529702/


All Articles