如何在 WPF 中更改 Button MouseOver 的背景?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17259280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you change Background for a Button MouseOver in WPF?
提问by Sepehr Mohammadi
I have a button on my page with this XAML:
我的页面上有一个带有此 XAML 的按钮:
<Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Bottom"
Width="50" Height="50" HorizontalContentAlignment="Left"
BorderBrush="{x:Null}" Foreground="{x:Null}" Margin="50,0,0,0">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="Green"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
But when I put mouse over my button, button's background changes to default windows gray background.
What's The Problem?
但是当我将鼠标放在按钮上时,按钮的背景会变为默认的 Windows 灰色背景。
有什么问题?
This is the button picture before and after mouseover:
Before:
After:
这是鼠标悬停前后的按钮图片:
之前:
之后:
回答by Richard E
To remove the default MouseOver
behaviour on the Button
you will need to modify the ControlTemplate
. Changing your Style
definition to the following should do the trick:
要删除 上的默认MouseOver
行为,Button
您需要修改ControlTemplate
. 将您的Style
定义更改为以下内容应该可以解决问题:
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="Black" BorderThickness="1">
<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>
EDIT: It's a few years late, but you are actually able to set the border brush inside of the border that is in there. Idk if that was pointed out but it doesn't seem like it was...
编辑:已经晚了几年,但您实际上可以在那里的边框内设置边框画笔。如果有人指出这一点,我想,但似乎不是......
回答by Peter Duniho
All of the answers so far involve completely replacing the default button behavior with something else. However, IMHO it is useful and important to understand that it's possible to change just the part you care about, by editing the existing, default template for a XAML element.
到目前为止,所有答案都涉及用其他东西完全替换默认按钮行为。但是,恕我直言,了解可以通过编辑 XAML 元素的现有默认模板,仅更改您关心的部分是有用且重要的。
In the case of dealing with the hover effect on a WPF button, the change in appearance in a WPF Button
element is caused by a Trigger
in the default style for the Button
, which is based on the IsMouseOver
property and sets the Background
and BorderBrush
properties of the top-level Border
element in the control template. The Button
element's background is underneath the Border
element's background, so changing the Button.Background
property doesn't prevent the hover effect from being seen.
在处理 WPF 按钮上的悬停效果的情况下,WPFButton
元素中外观的变化是由Trigger
的默认样式中的a 引起的,该样式Button
基于IsMouseOver
属性并设置顶级元素的Background
和BorderBrush
属性Border
在控制模板中。该Button
元素的背景是下面Border
元素的背景,因此更改Button.Background
属性不会阻止看到悬停效果。
With some effort, you could override this behavior with your own setter, but because the element you need to affect is in the template and not directly accessible in your own XAML, that approach would be difficult and IMHO overly complex.
通过一些努力,您可以使用自己的 setter 覆盖此行为,但由于您需要影响的元素位于模板中,并且不能在您自己的 XAML 中直接访问,因此这种方法将很困难,恕我直言过于复杂。
Another option would be to make use the graphic as the Content
for the Button
rather than the Background
. If you need additional content over the graphic, you can combine them with a Grid
as the top-level object in the content.
另一种选择是将图形用作Content
forButton
而不是Background
. 如果您需要图形上的附加内容,您可以将它们与Grid
作为内容中的顶级对象组合在一起。
However, if you literally just want to disable the hover effect entirely (rather than just hiding it), you can use the Visual Studio XAML Designer:
但是,如果您实际上只想完全禁用悬停效果(而不是仅仅隐藏它),则可以使用 Visual Studio XAML 设计器:
- While editing your XAML, select the "Design"tab.
- In the "Design"tab, find the button for which you want to disable the effect.
- Right-click that button, and choose "Edit Template/Edit a Copy...". Select in the prompt you get where you want the new template resource to be placed. This will appear to do nothing, but in fact the Designer will have added new resources where you told it, and changed your button element to reference the style that uses those resources as the button template.
- Now, you can go edit that style. The easiest thing is to delete or comment-out (e.g. Ctrl+E, C) the
<Trigger Property="IsMouseOver" Value="true">...</Trigger>
element. Of course, you can make any change to the template you want at that point.
- 在编辑 XAML 时,选择“设计”选项卡。
- 在“设计”选项卡中,找到要为其禁用效果的按钮。
- 右键单击该按钮,然后选择“编辑模板/编辑副本...”。在提示中选择要放置新模板资源的位置。这看起来什么都不做,但实际上设计器会在您告诉它的地方添加新资源,并更改您的按钮元素以引用使用这些资源作为按钮模板的样式。
- 现在,您可以编辑该样式。最简单的方法是删除或注释掉(例如Ctrl+ E, C)
<Trigger Property="IsMouseOver" Value="true">...</Trigger>
元素。当然,此时您可以对所需的模板进行任何更改。
When you're done, the button style will look something like this:
完成后,按钮样式将如下所示:
<p: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>
</p: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="#FFC4E5F6"/>
<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"/>
<p:Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
<!--<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
</Trigger>-->
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</p:Style>
(Note: you can omit the p:
XML namespace qualifications in the actual code…I provide them here only because the Stack Overflow XML code formatter gets confused by <Style/>
elements that don't have a fully-qualified name with XML namespace.)
(注意:您可以p:
在实际代码中省略XML 命名空间限定条件……我在这里提供它们只是因为 Stack Overflow XML 代码格式化程序会被<Style/>
那些没有完全限定名称的元素与 XML 命名空间混淆。)
If you want to apply the same style to other buttons, you can just right-click them and choose "Edit Template/Apply Resource"and select the style you just added for the first button. You can even make that style the default style for all buttons, using the normal techniques for applying a default style to elements in XAML.
如果要将相同的样式应用于其他按钮,只需右键单击它们并选择“编辑模板/应用资源”,然后选择刚刚为第一个按钮添加的样式。您甚至可以使用将默认样式应用于 XAML 中的元素的常规技术,使该样式成为所有按钮的默认样式。
回答by Contango
This worked well for me.
这对我来说效果很好。
Button Style
按钮样式
<Style x:Key="TransparentStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border>
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="DarkGoldenrod"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid Background="Transparent">
<ContentPresenter></ContentPresenter>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Button
按钮
<Button Style="{StaticResource TransparentStyle}" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25"
Command="{Binding CloseWindow}">
<Button.Content >
<Grid Margin="0 0 0 0">
<Path Data="M0,7 L10,17 M0,17 L10,7" Stroke="Blue" StrokeThickness="2" HorizontalAlignment="Center" Stretch="None" />
</Grid>
</Button.Content>
</Button>
Notes
笔记
- The button displays a little blue cross, much like the one used to close a window.
- By setting the background of the grid to "Transparent", it adds a hittest, which means that if the mouse is anywhere over the button, then it will work. Omit this tag, and the button will only light up if the mouse is over one of the vector lines in the icon (this is not very usable).
- 该按钮显示一个蓝色的小十字,很像用于关闭窗口的那个。
- 通过将网格的背景设置为“透明”,它添加了一个hittest,这意味着如果鼠标在按钮上的任何位置,那么它就会起作用。省略这个标签,只有当鼠标在图标中的一条矢量线上时按钮才会亮起(这不是很有用)。
回答by Justin Adrias
Just want to share my button style from my ResourceDictionary that i've been using. You can freely change the onHover background at the style triggers. "ColorAnimation To= *your desired BG(i.e #FFCEF7A0)". The button BG will also automatically revert to its original BG after the mouseOver state.You can even set how fast the transition.
只想从我一直在使用的 ResourceDictionary 分享我的按钮样式。您可以在样式触发器处自由更改 onHover 背景。“ ColorAnimation To= *您想要的BG(即#FFCEF7A0)”。在 mouseOver 状态后,按钮 BG 也会自动恢复到其原始 BG。您甚至可以设置过渡的速度。
Resource Dictionary
资源字典
<Style x:Key="Flat_Button" TargetType="{x:Type Button}">
<Setter Property="Width" Value="100"/>
<Setter Property="Height" Value="50"/>
<Setter Property="Margin" Value="2"/>
<Setter Property="FontFamily" Value="Arial Narrow"/>
<Setter Property="FontSize" Value="12px"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Opacity="1" Color="White"/>
</Setter.Value>
</Setter>
<Setter Property="Background" >
<Setter.Value>
<SolidColorBrush Opacity="1" Color="#28C2FF" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border"
SnapsToDevicePixels="True"
BorderThickness="1"
Padding="4,2"
BorderBrush="Gray"
CornerRadius="3"
Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter
Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="#D2F898"
Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)"
FillBehavior="HoldEnd" Duration="0:0:0.25" AutoReverse="False" RepeatBehavior="1x"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)"
FillBehavior="HoldEnd" Duration="0:0:0.25" AutoReverse="False" RepeatBehavior="1x"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
all you have to do is call the style.
您所要做的就是调用样式。
Example Implementation
示例实现
<Button Style="{StaticResource Flat_Button}" Height="Auto"Width="Auto">
<StackPanel>
<TextBlock Text="SAVE" FontFamily="Arial" FontSize="10.667"/>
</StackPanel>
</Button>
回答by Iakobos Karakizas
A slight more difficult answer that uses ControlTemplate and has an animation effect (adapted from https://docs.microsoft.com/en-us/dotnet/framework/wpf/controls/customizing-the-appearance-of-an-existing-control)
使用 ControlTemplate 并具有动画效果的稍微困难的答案(改编自https://docs.microsoft.com/en-us/dotnet/framework/wpf/controls/customizing-the-appearance-of-an-existing-控制)
In your resource dictionary define a control template for your button like this one:
在您的资源字典中为您的按钮定义一个控件模板,如下所示:
<ControlTemplate TargetType="Button" x:Key="testButtonTemplate2">
<Border Name="RootElement">
<Border.Background>
<SolidColorBrush x:Name="BorderBrush" Color="Black"/>
</Border.Background>
<Grid Margin="4" >
<Grid.Background>
<SolidColorBrush x:Name="ButtonBackground" Color="Aquamarine"/>
</Grid.Background>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="4,5,4,4"/>
</Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Color" To="Red"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Color" To="Red"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
in your XAML you can use the template above for your button as below:
在您的 XAML 中,您可以将上面的模板用于您的按钮,如下所示:
Define your button
定义你的按钮
<Button Template="{StaticResource testButtonTemplate2}"
HorizontalAlignment="Center" VerticalAlignment="Center"
Foreground="White">My button</Button>
Hope it helps
希望能帮助到你
回答by ángel Ibá?ez
For change button style
用于更改按钮样式
1st: define resource styles
第一:定义资源样式
<Window.Resources>
<Style x:Key="OvergroundIn" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="#FF16832F">
<ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="#FF06731F">
<ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="OvergroundOut" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="#FFF35E5E">
<ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="#FFE34E4E">
<ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
2nd define button code
第二个定义按钮代码
<Border Grid.Column="2" BorderBrush="LightGray" BorderThickness="2" CornerRadius="3" Margin="2,2,2,2" >
<Button Name="btnFichar" BorderThickness="0" Click="BtnFichar_Click">
<Button.Content>
<Grid>
<TextBlock Margin="0,7,0,7" TextAlignment="Center">Fichar</TextBlock>
</Grid>
</Button.Content>
</Button>
</Border>
3th code behind
后面的第三个代码
public void ShowStatus()
{
switch (((MainDto)this.DataContext).State)
{
case State.IN:
this.btnFichar.BorderBrush = new SolidColorBrush(Color.FromRgb(243, 94, 94));
this.btnFichar.Style = Resources["OvergroundIn"] as Style;
this.btnFichar.Content = "Fichar Salida";
break;
case State.OUT:
this.btnFichar.BorderBrush = new SolidColorBrush(Color.FromRgb(76, 106, 83));
this.btnFichar.Style = Resources["OvergroundOut"] as Style;
this.btnFichar.Content = "Fichar Entrada";
break;
}
}