Стиль MouseOver на кнопке Silverlight / WPF - PullRequest
13 голосов
/ 08 марта 2010

Борьба со стилем мыши над кнопкой ... Мне удалось стилизовать кнопку (сплошной красный), но я бы хотел, чтобы она менялась на сплошной черный при наведении мыши. Я новичок в XAML и вижу, что ему нужна какая-то доска объявлений / анимация ... не знаю точно, как это сделать.

Любая помощь будет принята с благодарностью.

Ответы [ 4 ]

17 голосов
/ 08 марта 2010

Это отличается от WPF для Silverlight. В WPF ответ Роба правильный.

В Silverlight это не сработает. Silverlight использует VisualStateManager вместо триггеров. Код для этого более сложный, но некоторые люди считают, что это лучше. Вам придется создать шаблон управления в своем стиле. (Для получения информации об определении шаблона элемента управления см. Эта статья . Самый простой способ создать аналогичный шаблон ControlTemplate - это использовать Expression Blend, который имеет функцию для полного извлечения существующего шаблона.) *

В шаблоне управления определите 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>
...

Важно также указать цвет переднего плана по умолчанию в стиле, как это делал Роб выше. Если вы укажете его вместо элемента управления, он переопределит значения из стиля.

Обратите внимание, что можно получить VisualStateManager из набора инструментов WPF, чтобы иметь аналогичное решение в WPF.

13 голосов
/ 08 марта 2010

В 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>
7 голосов
/ 08 марта 2010

В WPF:

Определите раскадровку в своих ресурсах (любое место, доступное по кнопке или ее стиль):

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

И в кнопке создайте триггер события, который запускает анимацию:

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

То, что вы хотите оживить, должно явно существовать. Вот почему в качестве фона явно задан SolidColorBrush, цвет которого изменяется в раскадровке.

Конечно, это должно быть сделано через стиль.

Silverlight поддерживает событие Loaded только для триггеров, поэтому вам нужно прикрепить к кнопке настоящий обработчик событий и запустить раскадровку программно.

5 голосов
/ 08 марта 2010

Да, Visual State Manager является ключевым здесь. Я только что загрузил бесплатную тему 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>
...