【问题标题】:Button's trigger IsMouseOver stops working after button's background is set in code-behind在代码隐藏中设置按钮的背景后,按钮的触发器 IsMouseOver 停止工作
【发布时间】:2021-05-24 11:58:32
【问题描述】:

我希望在光标悬停在按钮上时更改按钮的背景。
我设法以一种使用“IsMouseOver”触发器的样式来做到这一点,该触发器将按钮的背景设置为红色。

当点击事件发生时,我还希望按钮在两种颜色之间改变它的背景。
我已经设法在窗口的代码隐藏中做到这一点,它在蓝色和绿色之间切换。

问题
只要我不点击按钮,触发器就会按预期工作。
当我单击按钮时,背景会按预期更改为蓝色或绿色。
如果我随后将按钮悬停,则在光标悬停时背景不会设置为红色。

XAML 代码

<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>

窗口代码隐藏

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

我怀疑触发器确实有效,但问题出在其他地方。

可能是什么问题?
如何解决?

【问题讨论】:

    标签: c# wpf button triggers ismouseover


    【解决方案1】:

    可能是什么问题?

    docs 中所述,本地值优先于样式设置器和触发器这一事实。

    如何解决?

    例如,将触发器移动到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>
    

    【讨论】:

    • 感谢@mm8 的解释。我已经尝试过使用模板触发器的解决方案,所以我重试了。但是还是不行。
    • 是的,确实如此。我猜你没有复制和粘贴我的示例Style。再试一次。
    • 谢谢@mm8。我没有粘贴整个样式:D
    【解决方案2】:

    <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;
                }
    

    【讨论】:

    • 我相信你应该在你的答案中添加一个解释。
    • 您的解决方案 @zia khan 不起作用。由于默认颜色是蓝色,因此在样式的设置器之一中指定。当 ClearValue() 返回默认背景时,很难切换到绿色。它有点工作,但我公司的设计师永远不会接受它。
    • 你不能说我的解决方案不起作用。但它的解决方式,是不可接受的。这就是你说的?
    • 是的@ziakhan。我不想失礼。
    猜你喜欢
    • 2013-10-18
    • 1970-01-01
    • 2013-11-08
    • 1970-01-01
    • 2014-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多