在 Silverlight/WPF 按钮上设置 MouseOver 的样式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2401519/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 21:33:23  来源:igfitidea点击:

Style the MouseOver on a Silverlight/WPF button

wpfsilverlightxamlstyling

提问by mattruma

Struggling with styling the mouse over for a button ... I have managed to style the button (solid red), but I would like for it to change to solid black whenever a mouse over occurs. I am new to XAML, and I can see that it wants some type of story board/animation ... not sure exactly how to do this.

努力为按钮设置鼠标样式......我已经设法设置按钮样式(纯红色),但我希望它在鼠标悬停时更改为纯黑色。我是 XAML 的新手,我可以看到它需要某种类型的故事板/动画......不确定如何做到这一点。

Any help would be greatly appreciated.

任何帮助将不胜感激。

回答by Ben Von Handorf

This is different from WPF to Silverlight. In WPF, the answer from Rob is correct.

这与 WPF 到 Silverlight 不同。在 WPF 中,Rob 的答案是正确的。

In Silverlight, this won't work. Silverlight uses the VisualStateManager instead of triggers. The code for this is more complex, but some people feel that this is better. You wind up having to create a control template in your style. (For information on defining the control template, see This Article. The easiest way to create a similar ControlTemplate is to use Expression Blend, which has a function to extract the existing template in full for you.)

在 Silverlight 中,这不起作用。Silverlight 使用 VisualStateManager 而不是触发器。这个的代码比较复杂,但也有人觉得这样更好。您最终不得不以您的风格创建一个控件模板。(有关定义控件模板的信息,请参阅本文。创建类似 ControlTemplate 的最简单方法是使用 Expression Blend,它具有为您完整提取现有模板的功能。)

In the control template, define the VisualState you care about and what you want to happen.

在控件模板中,定义您关心的 VisualState 以及您想要发生的事情。

<VisualStateGroup x:Name="CommonStateGroup">
    <VisualState x:Name="MouseOverState">
        <Storyboard>
            <ColorAnimation Storyboard.TargetName="TopmostElementOfTheTemplate" 
                                       Storyboard.TargetProperty="Foreground" 
                                       To="Black"
                                       Duration="00:00:00" >
            </ColorAnimation>
        </Storyboard>
    </VisualState>
</VisualStateGroup>
...

It is important to specify the default foreground color in the style as well, as Rob did above. If you specify it on the control instead it will override values from the style.

在样式中指定默认前景色也很重要,就像 Rob 上面所做的那样。如果您在控件上指定它,它将覆盖样式中的值。

Note that it is possible to get the VisualStateManager out of the WPF Toolkit to have a similar solution in WPF.

请注意,可以从 WPF Toolkit 中获取 VisualStateManager 以在 WPF 中具有类似的解决方案。

回答by Rob Fonseca-Ensor

In WPF, you don't need a storyboard unless you want an animation:

在 WPF 中,除非您想要动画,否则您不需要故事板:

    <Button Content="Hover me">
        <Button.Style>
            <Style TargetType="Button">
                <Setter Property="Background" Value="Red"/>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="Black"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>

回答by Timores

In WPF:

在 WPF 中:

Define a storyboard in your resources (any place accessible from the button or its style):

在您的资源中定义故事板(可通过按钮或其样式访问的任何位置):

  <Window.Resources>
    <Storyboard x:Key="buttonAnim">
      <ColorAnimation Storyboard.TargetName="_back" Storyboard.TargetProperty="Color" To="Red" />
    </Storyboard>
  </Window.Resources>

And in the button, create an event trigger that launches the animation:

在按钮中,创建一个启动动画的事件触发器:

<Button>
   <Button.Background>
      <SolidColorBrush Color="Blue" x:Name="_back" />
   </Button.Background>
   <Button.Triggers>
      <EventTrigger RoutedEvent="Button.MouseEnter">
          <BeginStoryboard Storyboard="{StaticResource buttonAnim}" />
      </EventTrigger>
   </Button.Triggers>
   Button Text
</Button>

What you want to animate must explicitly exist. This is why the background is explicitly set a SolidColorBrush, whose color is changed by the storyboard.

您想要设置动画的内容必须明确存在。这就是为什么背景被明确设置为 SolidColorBrush,其颜色由故事板更改。

Of course, this should be done through a Style.

当然,这应该通过 Style 来完成。

Silverlight only supports the Loaded event on triggers, so you need to attach a real event handler to the button and start the storyboard programatically.

Silverlight 仅支持触发器上的 Loaded 事件,因此您需要将真正的事件处理程序附加到按钮并以编程方式启动故事板。

回答by felixthehat

Yep, Visual State Manager is the key here. I just uploaded a free Silverlight theme to my blog http://www.blackspike.com/site/silverlight/free-silverlight-4-beta-skin- you can help yourself to the styles there, here is the xaml for a styled button

是的,视觉状态管理器是这里的关键。我刚刚上传了一个免费的 Silverlight 主题到我的博客http://www.blackspike.com/site/silverlight/free-silverlight-4-beta-skin- 你可以帮助自己选择那里的样式,这里是样式的 xaml按钮

    <SolidColorBrush x:Key="Brush_WindowBackground" Color="#FF333333"/>

<SolidColorBrush x:Key="Brush_Foreground" Color="#FFE5E5E5"/>

<SolidColorBrush x:Key="Brush_Highlight" Color="White"/>

<LinearGradientBrush x:Key="Brush_BackgroundGrad" EndPoint="0.5,1" StartPoint="0.5,0">
    <GradientStop Color="#FF3F3F3F" Offset="0"/>
    <GradientStop Color="#FF353535" Offset="0.3"/>
</LinearGradientBrush>

<LinearGradientBrush x:Key="Brush_BackgroundGrad_Over" EndPoint="0.5,1" StartPoint="0.5,0">
    <GradientStop Color="#FF474747" Offset="0"/>
    <GradientStop Color="#FF2F2F2F" Offset="0.3"/>
</LinearGradientBrush>

<LinearGradientBrush x:Key="Brush_BackgroundGrad_Down" EndPoint="0.5,1" StartPoint="0.5,0">
    <GradientStop Color="#FF1D1D1D" Offset="0"/>
    <GradientStop Color="#FF181818" Offset="0.3"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="Brush_BorderInner" Color="Black"/>

<SolidColorBrush x:Key="Brush_BorderOuter" Color="#FF434343"/>


<Style TargetType="Button">
    <Setter Property="Foreground" Value="{StaticResource Brush_Foreground}"/>
    <Setter Property="FontFamily" Value="Arial"/>
    <Setter Property="FontSize" Value="12"/>
    <Setter Property="Padding" Value="15,10"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualStateGroup.Transitions>
                                <VisualTransition GeneratedDuration="0:0:0.2"/>
                            </VisualStateGroup.Transitions>
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="background_over" d:IsOptimized="True"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="background_down" d:IsOptimized="True"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <DoubleAnimation Duration="0" To="0.2" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="contentPresenter" d:IsOptimized="True"/>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Rectangle x:Name="blackframe" Stroke="{StaticResource Brush_BorderOuter}" Fill="{StaticResource Brush_BorderInner}"/>
                    <Rectangle x:Name="background" Margin="2" Fill="{StaticResource Brush_BackgroundGrad}"/>
                    <Rectangle x:Name="background_over" Margin="2" Opacity="0" Fill="{StaticResource Brush_BackgroundGrad_Over}"/>
                    <Rectangle x:Name="background_down" Margin="2" Opacity="0" Fill="{StaticResource Brush_BackgroundGrad_Down}"/>
                    <ContentPresenter x:Name="contentPresenter" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="{TemplateBinding Padding}"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>