Majid
Majid

Reputation: 3471

Auto hover color for buttons based on their Background color

I've googled a lot but I've found nothing about this situation.

I have several flat Buttons with different Background colors, but the hover color is the same for all of them! I want each Button has its own hover color based on its background, for example gets a little lighter.

I've tried making custom styles and I reduced the Opacity in IsMouseOver trigger, but It's not what I want because it also affects the content of the button and not only the background color!

Win32 C# applications have a Flat Appearance property that do the trick automatically. When you choose a color for the BackColor and set the button as Flat, it takes care of all states color (Hover color, Disabled color, ...), however I've no idea how to do this in WPF.

Thank you in advance

Upvotes: 0

Views: 6268

Answers (2)

Justin XL
Justin XL

Reputation: 39006

the hover color is the same for all of them!

This is probably because in your Button's style, you have one single Background brush when IsMouseOver is True.

because it also affects the content of the button and not only the background color

This is probably because when the panel (likely a Border) you are animating is also the parent of the content control(e.g. ContentPresenter, ContentControl), so the Opaciy of this content control is also affected.

To solve these problems, you just need to create some visual elements (e.g. Rectangles, Borders) at the same level as your content control, and animate them based on which trigger is activated.

Here is a simple example.

<Window.Resources>
    <Style x:Key="FocusVisual">
        <Setter Property="Control.Template">
            <Setter.Value>
                <ControlTemplate>
                    <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
    <SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
    <SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
    <SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
    <SolidColorBrush x:Key="Button.Pressed.Background" Color="#FF737B7F"/>
    <SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
    <SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
    <SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
    <SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
    <Style x:Key="MyButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
        <Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
        <Setter Property="BorderBrush" Value="Transparent"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="HorizontalContentAlignment" Value="Center"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Padding" Value="4"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid SnapsToDevicePixels="true">
                        <Rectangle x:Name="BackgroundVisual" Fill="{TemplateBinding Background}"/>
                        <Rectangle x:Name="PressedVisual" Fill="{DynamicResource Button.Pressed.Background}" Opacity="0"/>
                        <Rectangle x:Name="DisabledVisual" Fill="{DynamicResource Button.Disabled.Background}" Opacity="0"/>
                        <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsDefaulted" Value="true"/>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter Property="Opacity" TargetName="BackgroundVisual" Value="0.6"/>
                        </Trigger>
                        <Trigger Property="IsPressed" Value="true">
                            <Setter Property="Opacity" TargetName="PressedVisual" Value="1"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
                            <Setter Property="Opacity" TargetName="DisabledVisual" Value="1"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="BorderThickness" Value="0"/>
    </Style>
</Window.Resources>

Here is how the style looks.

enter image description here

Hope this helps! :)

Upvotes: 4

Hana Bzh
Hana Bzh

Reputation: 2260

Check this out :

http://learnwpf.com/post/2006/03/06/How-do-I-change-an-items-appearance-on-mouseover-in-WPF.aspx

for Background you can simply set the "Background" property instead of setting the "BitmapEffect" property.

Hope this helps

Regards

Upvotes: 0

Related Questions