TemplateBinding fails when the target is ImageBrush.ImageSource

Why TemplateBindingdoes it seem to fail in this particular case?

Take the basic advanced button:

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);
    }
}

The management template shows the icon with OpacityMask:

<Style TargetType="controls:IconButton">
    <Setter Property="Width" Value="30" />
    <Setter Property="Height" Value="30" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="controls:IconButton">
                <Grid>
                    <Rectangle Fill="{StaticResource PhoneForegroundBrush}"
                               Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
                        <Rectangle.OpacityMask>
                            <ImageBrush ImageSource="{TemplateBinding Icon}" />
                        </Rectangle.OpacityMask>
                    </Rectangle>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

This fails - the control appears as a solid rectangle. If I use a regular image instead ImageBrush, then the binding will succeed:

            <ControlTemplate TargetType="controls:IconButton">
                <Grid>
                    <Image Source="{TemplateBinding Icon}" />
                </Grid>
            </ControlTemplate>

It also works correctly if I hardcode the image source path:

            <ControlTemplate TargetType="controls:IconButton">
                <Grid>
                    <Rectangle Fill="{StaticResource PhoneForegroundBrush}"
                               Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
                        <Rectangle.OpacityMask>
                            <ImageBrush ImageSource="/Images/appbar.next.rest.png" />
                        </Rectangle.OpacityMask>
                    </Rectangle>
                </Grid>
            </ControlTemplate>

So why does TemplateBindingit fail inside ImageBrush?


Update

By deduction (and thanks to Chris's answer), the following factors are possible:

, , ...

+4
2

, , , , , .

: WPF TemplateBinding vs RelativeSource TemplatedParent , , . -

"TemplateBindings . int ( ).

, WPF- string/URI ImageSource ( ImageSource - , ).

, . , , .

: , ImageBrush, FrameworkElement: ImageBrush DependencyProperty

+1

. Bizarrely RelativeSource TemplatedParent TemplateBinding .

<ImageBrush ImageSource="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Icon}" />

... , ? .

+4

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


All Articles