silverLight: OpacityMask won't apply on custom control

531 views Asked by At

I'm graying out images on disabled ImageButton custom controls by applying OpacityMask on an Overlay. The intended effect is that only the body of an image is grayed out, so no border or box is laid over the image.

The problem is: As far as image URI is accessed through a bound getter (the thing written in {TemplateBinding XXX}) the mask would not apply. However if the URI is stated explicitly, the mask would work. So the question is, why the problem occurs in case of TmplateBinding and how to resolve it.

The XAML code defining the custom Image Button is:

            <my1:ImageButton Height="24" Width="24" x:Name="imageButton1" IsEnabled="False" ImageSource="/SilverlightApplication4;component/Undo_24x24.png" Margin="178,75,198,201">
            <Image Source="/SilverlightApplication4;component/Undo_24x24.png" Height="24" Width="24" />
        </my1:ImageButton>

The custom property handler code is:

    public class ImageButton: Button
{
    public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(ImageButton), new PropertyMetadata(null));
    public ImageSource ImageSource
    {
        get
        {
            return (ImageSource)this.GetValue(ImageSourceProperty);
        }
        set
        {
            this.SetValue(ImageSourceProperty, value);
        }
    }
}

The style code of the custom control (disabled state):

                            <Rectangle x:Name="DisabledVisualElement" Fill="Red" Opacity="0" >
                            <Rectangle.OpacityMask>
                                <ImageBrush ImageSource="{TemplateBinding ImageSource}"/>                                   
                            </Rectangle.OpacityMask>
                        </Rectangle>

interestingly is that both, the following code snippets placed inside the style template

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

as well as

                            <Rectangle x:Name="DisabledVisualElement" Fill="Red" Opacity="0" >
                            <Rectangle.OpacityMask>
                                <ImageBrush ImageSource="/SilverlightApplication4;component/Undo_24x24.png"/>                                   
                            </Rectangle.OpacityMask>
                        </Rectangle>

both work correctly. So the problem seems to lie on that that ImageSource="{TemplateBinding ImageSource}" somehow does not retrieve the correct URI or does not work for some other reason. So, how to correct this?

1

There are 1 answers

0
Emond On

TemplateBinding isn't as fully featured as the regular binding. TemplateBinding is not able to automatically convert the string/uri into an actual bitmap.

Solution (use a regular binding):

<Rectangle x:Name="DisabledVisualElement" Fill="Red" Opacity="0" >
    <Rectangle.OpacityMask>
        <ImageBrush ImageSource="{Binding Path=ImageSource, RelativeSource={RelativeSource TemplatedParent}}"/>                                   
    </Rectangle.OpacityMask>
</Rectangle>