Style the MouseOver on a Silverlight/WPF button

前端 未结 4 1060
轮回少年
轮回少年 2021-02-19 11:27

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 oc

相关标签:
4条回答
  • 2021-02-19 12:14

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

        <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>
    
    0 讨论(0)
  • 2021-02-19 12:18

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

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

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

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

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

    0 讨论(0)
  • 2021-02-19 12:19

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

    Of course, this should be done through a 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.

    0 讨论(0)
  • 2021-02-19 12:24

    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

        <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>
    
    0 讨论(0)
提交回复
热议问题