WPF 样式 按钮 鼠标悬停 问题

9
我会尽力为您进行翻译。以下是所需翻译内容:

我正在尝试在按钮上制作一个简单的鼠标悬停效果,当鼠标悬停时,它确实会改变颜色,但颜色立即更改为默认按钮背景... 我该如何覆盖此行为?

这是我的代码:

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;
2个回答

24

根据这篇文章,那个华丽的动画是内置的,如果想要去除它,你需要重写 ButtonControlTemplate。幸运的是,这并不太难。我使用了这篇文章作为参考,并得出了以下的 Style,给你一个思路。

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

更新: 如果你一定要在代码中应用Style,并且不想使用ResourceDictionary(可能是更好的方式),你可以使用XamlReader.Load动态加载Style

            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;

你可以将样式放在资源字典中,然后在需要应用到按钮时取出来。 - Metro Smurf
当样式触发器在“IsMouseOver”上时,尽管触发器中唯一的样式是透明度,但之前定义的Button.Background.ImageBrush会消失。有什么建议吗?谢谢。 - Munchies

4

覆盖ButtonChrome主题会更容易。

创建一个模板并删除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>

然后添加你自己的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>

那应该解决了! :)

你应该提到如何注册Microsoft_Windows_Themes,添加 xmlns:themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" 并将 PresentationFramework.Aero 添加到项目引用中。 - psulek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接