Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Styles Button MouseOver Question

Tags:

c#

styles

wpf

I am trying to make a simple mouseover effect on a button, It does change the color when mouse is over but the color is immediately changed to the default button background... how can I override this behavior?

this is my code:

Style myBtnStyle = new Style();
Trigger bla = new Trigger() { Property = IsMouseOverProperty, Value = true };
bla.Setters.Add(new Setter(Control.BackgroundProperty, Brushes.Black));
myBtnStyle.Triggers.Add(bla);
button2.Style = myBtnStyle;
like image 653
Luiscencio Avatar asked Apr 21 '10 23:04

Luiscencio


2 Answers

According to this post, that fancy animation is built into and to remove it, you're going to need to override the ControlTemplate for your Button. Fortunately, that isn't too hard. I used this post as source material and came up with the following Style that gives you the idea.

<Style x:Key="MouseOverButtonStyle" TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <ControlTemplate.Resources>
                    <Style x:Key="ShadowStyle">
                        <Setter Property="Control.Foreground" Value="LightGray" />
                    </Style>
                </ControlTemplate.Resources>
                <Border Name="border" BorderThickness="1" Padding="4,2" BorderBrush="DarkGray" CornerRadius="3" Background="{TemplateBinding Background}">
                    <Grid >
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Name="contentShadow" Style="{StaticResource ShadowStyle}">
                            <ContentPresenter.RenderTransform>
                                <TranslateTransform X="1.0" Y="1.0" />
                            </ContentPresenter.RenderTransform>
                        </ContentPresenter>
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Name="content"/>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Background" Value="Beige" />
        </Trigger>
    </Style.Triggers>
</Style>

Update: If you're dead set on applying the Style in code and you don't want to use a ResourceDictionary (probably the better way to do it), you can load the Style dynamically using XamlReader.Load:

            const string xaml = @"
<Style xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
       xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
       TargetType='Button'>
    <Setter Property='Template'>
        <!--- Omitted For Clarity --->
    </Setter>
    <Style.Triggers>
        <Trigger Property='IsMouseOver' Value='True'>
            <Setter Property='Background' Value='Beige' />
        </Trigger>
    </Style.Triggers>
</Style>";
            var encoding = new ASCIIEncoding();
            var bytes = encoding.GetBytes(xaml);
            var style = (Style)XamlReader.Load(new MemoryStream(bytes));
            Button1.Style = style;
like image 114
Joseph Sturtevant Avatar answered Nov 02 '22 19:11

Joseph Sturtevant


Overriding the ButtonChrome theme would be easier.

Create a template and remove the RenderMouseOver="{TemplateBinding IsMouseOver}"

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="Button">
            <Microsoft_Windows_Themes:ButtonChrome x:Name="Chrome" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}"RenderPressed="{TemplateBinding IsPressed}" RenderDefaulted="{TemplateBinding Button.IsDefaulted}" SnapsToDevicePixels="True">
                <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
            </Microsoft_Windows_Themes:ButtonChrome>
            <ControlTemplate.Triggers>
                <Trigger Property="IsKeyboardFocused" Value="True">
                    <Setter Property="RenderDefaulted" TargetName="Chrome" Value="True"/>
                </Trigger>
                <Trigger Property="ToggleButton.IsChecked" Value="True">
                    <Setter Property="RenderPressed" TargetName="Chrome" Value="True"/>
                </Trigger>
                <Trigger Property="IsEnabled" Value="False">
                    <Setter Property="Foreground" Value="#FFADADAD"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Setter.Value>
</Setter>

And then add your own handling of mouseover

    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Background">
                <Setter.Value>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FFF3E8D5" Offset="0"/>
                        <GradientStop Color="#FFF49B03" Offset="1"/>
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
        </Trigger>
    </Style.Triggers>

That should solve it! :)

like image 39
Kman Avatar answered Nov 02 '22 18:11

Kman