-1

I'm kinda new to WPF/XAML

I have this Button that holds a stack panel which is having an Image and a Textbox Control to it.

I have styled the button in a StaticResource

How can I achieve an image change on MouseOver?

I have accomplished changing the Background color, and the Foreground color (text) to change on mouseover, but I can't get the image change to work

This is my Button:

                <Button Style="{StaticResource mainMenuHomeBtn}">
                    <StackPanel
                        Orientation="Horizontal"
                        HorizontalAlignment="Left">
                        <Image Name="hjemImage" Margin="5" Height="30" Source="/Images/fal-home-lg-alt.png"/>
                        <TextBlock Margin="10" VerticalAlignment="Center" Text="Hjem"/>
                    </StackPanel>
                </Button>

And this is my Button Styling:

        <Style x:Key="mainMenuHomeBtn" TargetType="{x:Type Button}">
            <Setter Property="Width" Value="auto"/>
            <Setter Property="Height" Value="auto"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="Padding" Value="-2"/>
            <Setter Property="Foreground" Value="#e3e3e3"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Border Background="{TemplateBinding Background}" BorderBrush="#cccccc" BorderThickness="0">
                            <ContentPresenter HorizontalAlignment="Left"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Foreground" Value="#696969"/>
                    <Setter Property="Background" Value="#d9d9d9"/>
                </Trigger>
                <Trigger Property="IsPressed" Value="True">
                    <Setter Property="Background" Value="#e3e3e3"/>
                </Trigger>
            </Style.Triggers>
        </Style>
Kirollos Mallak
  • 359
  • 4
  • 12
  • 1
    In order to implement an "image change" in a Button Style, the Style would have to declare a Template that contains an Image element, instead of just a ContentPresenter. Perhaps move the StackPanel with the Image into the ControlTemplate and use a ContentPresenter instead of the TextBlock. – Clemens Dec 03 '21 at 08:18
  • Can you give an example, as i'm new to XAML and WPF? =) – Michael Ejvind Therkildsen Dec 03 '21 at 08:39
  • 1
    https://stackoverflow.com/a/1933156/1136211 There is plenty of similar stuff here on StackOverflow. – Clemens Dec 03 '21 at 08:46
  • Didn't have any luck with that. I'll just go with the next best thing. Just slightly tint my mouseover background, so i can use the same picture.. – Michael Ejvind Therkildsen Dec 03 '21 at 11:46

1 Answers1

1

Your Style/ControlTemplate doesn't know anything about the StackPanel that happens to be in the element that is currently set as the Content of the Button element that the Style is currently applied to.

You could move the contents to the template and use a trigger so change the Source of the Image element in the template:

<Style x:Key="mainMenuHomeBtn" TargetType="{x:Type Button}">
    <Setter Property="Width" Value="auto"/>
    <Setter Property="Height" Value="auto"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="HorizontalContentAlignment" Value="Left"/>
    <Setter Property="Padding" Value="-2"/>
    <Setter Property="Foreground" Value="#e3e3e3"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border Background="{TemplateBinding Background}" BorderBrush="#cccccc" BorderThickness="0">
                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
                        <Image Name="hjemImage" Margin="5" Height="30" Source="/Images/fal-home-lg-alt.png"/>
                        <TextBlock Margin="10" VerticalAlignment="Center" Text="Hjem"/>
                    </StackPanel>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="hjemImage" Property="Source" Value="pic.png" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Foreground" Value="#696969"/>
            <Setter Property="Background" Value="#d9d9d9"/>
        </Trigger>
        <Trigger Property="IsPressed" Value="True">
            <Setter Property="Background" Value="#e3e3e3"/>
        </Trigger>
    </Style.Triggers>
</Style>

Then there is no point of setting the Content property since there is no ContentPresenter in the Style:

<Button Style="{StaticResource mainMenuHomeBtn}" />

The other option is to keep your Style as-is and add a DataTrigger that binds to the IsMouseOver property of the Button to an element in the content:

<Button Style="{StaticResource mainMenuHomeBtn}">
    <StackPanel Orientation="Horizontal"
                HorizontalAlignment="Left">
        <Image Name="hjemImage" Margin="5" Height="30">
            <Image.Style>
                <Style TargetType="Image">
                    <Setter Property="Source" Value="/Images/fal-home-lg-alt.png" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType=Button}}"
                                     Value="True">
                            <Setter Property="Source" Value="pic.png" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Image.Style>
        </Image>
        <TextBlock Margin="10" VerticalAlignment="Center" Text="Hjem"/>
    </StackPanel>
</Button>
mm8
  • 163,881
  • 10
  • 57
  • 88
  • Thanks a lot. I chose the last of your options where you define the Datatrigger for the button it self, as I have more than just the homebutton, with different pictures and texts. It works like a charm. – Michael Ejvind Therkildsen Dec 06 '21 at 10:23