简体   繁体   中英

Button's trigger IsMouseOver stops working after button's background is set in code-behind

I want the background of a button to change when the cursor hovers over the button.
I have managed to do this in a style which use the "IsMouseOver" trigger which sets the button's background to red.

I also want the button to alter it's background between two colors when the click event occurs.
I have managed to do this in the code-behind of the Window which switches between blue and green.

The problem
The trigger works as expected as long as I don't click the button.
When I click the button, the background is changed to either blue or green as expected.
If I then afterwards hover the button, the background is not set to red while hovering with the cursor.

XAML-code

<Window x:Class="Main.MainWindow">

    <Window.Resources>
        <Style x:Key="FooStyle" TargetType="Button">
            <Setter Property="Foreground" Value="White" />
            <Setter Property="FontSize" Value="12" />
            <Setter Property="Background" Value="Blue" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Border Background="{TemplateBinding Background}" BorderBrush="Transparent">
                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="Red" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>

    <StackPanel Orientation="Vertical">
        <Button x:Name="btnFoo"
                Content="Foo"
                Width="100" 
                Click="Foo_Click" 
                Style="{StaticResource FooStyle}" />
    </StackPanel>

</Window>

Window code-behind

private void Foo_Click(object sender, RoutedEventArgs e)
{
    btnFoo.Background = btnFoo.Background == Brushes.Blue ? Brushes.Lime : Brushes.Blue;
}

I suspect the trigger actually works but it something else here which is the problem.

What could be the problem?
How to solve this?

What could be the problem?

The fact that local values take precedence over style setters and triggers as explained in the docs .

How to solve this?

For example by moving the trigger to the ControlTemplate :

<Style x:Key="FooStyle" TargetType="Button">
    <Setter Property="Foreground" Value="White" />
    <Setter Property="FontSize" Value="12" />
    <Setter Property="Background" Value="Blue" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="Transparent">
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="border" Property="Background" Value="Red" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

在此处输入图像描述

<Window.Resources>
            <Style x:Key="FooStyle" TargetType="Button">
                <Setter Property="Foreground" Value="White" />
                <Setter Property="FontSize" Value="12" />
                <Setter Property="Background" Value="Blue" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Button}">
                            <Border Background="{TemplateBinding Background}" BorderBrush="Transparent">
                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="Red" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Window.Resources>
        <Grid>
            <StackPanel Orientation="Vertical">
                <Button x:Name="btnFoo"
                    Content="Foo"
                    Width="100" 
                    Click="BtnFoo_Click" 
                    MouseEnter="BtnFoo_MouseEnter"
                    MouseLeave="BtnFoo_MouseLeave"
                    Style="{StaticResource FooStyle}" />
            </StackPanel>
    
        </Grid>

Code Behind

    Brush color { get; set; }
            private void BtnFoo_Click(object sender, RoutedEventArgs e)
            {
                color= color == Brushes.Lime ? Brushes.Blue : Brushes.Lime;
                btnFoo.Background = color;
            }
    
            private void BtnFoo_MouseEnter(object sender, MouseEventArgs e)
            {
              
                btnFoo.ClearValue(Button.BackgroundProperty);
            }
    
            private void BtnFoo_MouseLeave(object sender, MouseEventArgs e)
            {
                btnFoo.Background = color==null?btnFoo.Background:color;
            }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM