Search code examples
c#silverlightxamlsilverlight-5.0visualstatemanager

Silverlight - Style ALL Image Buttons to Change on MouseOver


I'm having a really hard time finding a way to do the following...

I have my "Image button style," and it is applied to every button in my Silverlight app. Is there any way to make a blanket VisualStateManager to change the image on MouseOver, that will work for every button? I have a couple ideas, but I'm not sure if they can be implemented...

Let's say my button image paths are consistent:

  • image1.png
  • image2.png

and

  • image1 - hover.png
  • image2 - hover.png

Is there a way to change the path of the image to append " - hover"? I thought about using an IValueConverter for this, but wasn't sure how to access the control state...

An alternative idea I had was if there was a way to accomplish this:

<Button>
    <Image Source="../Images/image1.png" Width="70"/>
    <Image Source="../Images/image1 - hover.png" Width="70"/>
</Button>

Have two contents (an array of content?) and on Normal state, set only the first content opacity to 1, and the rest to 0. Then on MouseOver, switch the opacities.

Are any of these solutions feasible, and how can they be implemented?

Thanks


Edit: I know I can make custom styles for each button that switch out their images, but I would like a blanket style that I can apply to all buttons.


Solution

  • You may (ab)use the Tag property for your purpose and create a ControlTemplate with two Image controls with a BitmapImage that binds its UriSource property to either the Content or the Tag property respectively:

    <Style TargetType="Button">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup Name="CommonStates">
                                <VisualState Name="Normal"/>
                                <VisualState Name="MouseOver">
                                    <Storyboard>
                                        <DoubleAnimation
                                            Storyboard.TargetName="image1"
                                            Storyboard.TargetProperty="Opacity"
                                            To="0" Duration="0:0:0.1"/>
                                        <DoubleAnimation
                                            Storyboard.TargetName="image2"
                                            Storyboard.TargetProperty="Opacity"
                                            To="1" Duration="0:0:0.1"/>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Image x:Name="image1">
                            <Image.Source>
                                <BitmapImage UriSource="{Binding Content,
                                    RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
                            </Image.Source>
                        </Image>
                        <Image x:Name="image2" Opacity="0">
                            <Image.Source>
                                <BitmapImage UriSource="{Binding Tag,
                                    RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
                            </Image.Source>
                        </Image>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    Now you may declare a Button like this:

    <Button Content="../Images/image1.png" Tag="../Images/image1_hover.png"/>