WPF Focused Visual State срабатывает только при нажатии кнопки, почему?
Что касается приведенного ниже кода, может ли кто-нибудь сказать мне, почему, когда кнопка находится в нормальном состоянии, а также в сфокусированном состоянии, кнопка не отскакивает? Другими словами, не должна ли кнопка отскакивать всякий раз, когда она находится в состоянии фокусировки, независимо от того, нажата она или нет?
<Window x:Class="ButtonTemplateUsingVSM.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="249" Width="619">
<Window.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Background" Value="Black"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid RenderTransformOrigin=".5,.5">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal"/>
<VisualState Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="outerCircle"
Storyboard.TargetProperty="(Ellipse.Fill).(LinearGradientBrush.GradientStops)[1].(GradientStop.Color)"
To="Orange" Duration="0:0:.4"/>
</Storyboard>
</VisualState>
<VisualState Name="Pressed">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleX" To=".9" Duration="0"/>
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleY" To=".9" Duration="0"/>
</Storyboard>
</VisualState>
<VisualState Name="Disabled">
<Storyboard>
<ColorAnimation Storyboard.TargetName="outerCircle"
Storyboard.TargetProperty="(Ellipse.Fill).(LinearGradientBrush.GradientStops)[1].(GradientStop.Color)"
To="Gray" Duration="0:0:.4"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup Name="FocusStates">
<VisualState Name="Unfocused"/>
<VisualState Name="Focused">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Grid.RenderTransform).(TransformGroup.Children)[1].(TranslateTransform.Y)"
To="-20" AutoReverse="True" RepeatBehavior="Forever" Duration="0:0:.4">
<DoubleAnimation.EasingFunction>
<QuadraticEase/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="scaleTransform"/>
<TranslateTransform x:Name="translateTransform"/>
</TransformGroup>
</Grid.RenderTransform>
<Ellipse x:Name="outerCircle">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0"
Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background.Color}"/>
<GradientStop x:Name="highlightGradientStop" Offset="1" Color="Red"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse RenderTransformOrigin=".5,.5">
<Ellipse.RenderTransform>
<ScaleTransform ScaleX=".8" ScaleY=".8"/>
</Ellipse.RenderTransform>
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="White"/>
<GradientStop Offset="1" Color="Transparent"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Viewbox>
<ContentPresenter Margin="{TemplateBinding Padding}"/>
</Viewbox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel Orientation="Horizontal">
<Button Height="200" Width="200" FontSize="20" Padding="20" Margin="5">OK</Button>
<Button Height="200" Width="200" FontSize="20" Padding="20" Margin="5">OK</Button>
<Button Height="200" Width="200" FontSize="20" Padding="20" Margin="5">OK</Button>
<Button Height="200" Width="200" FontSize="20" IsEnabled="False" Padding="20" Margin="5">OK</Button>
<Button Height="200" Width="200" FontSize="20" Padding="20" Margin="5">OK</Button>
</StackPanel>
</Window>
namespace ButtonTemplateUsingVSM
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
1 ответ
По умолчанию кнопка получает фокус только при нажатии (если вы не изменили ее в коде). Вы также можете получить фокус клавиатуры. Таким образом, ваша подпрыгивающая анимация будет работать только при нажатии одной из этих кнопок, поскольку она настроена только для Focused
государство:
<VisualStateGroup Name="FocusStates">
<VisualState Name="Unfocused"/> <!--Right here-->
<VisualState Name="Focused">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Grid.RenderTransform).(TransformGroup.Children)[1].(TranslateTransform.Y)"
To="-20" AutoReverse="True" RepeatBehavior="Forever"
Duration="0:0:.4">
<DoubleAnimation.EasingFunction>
<QuadraticEase/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</VisualState>
</VisualStateGroup>
Как вы видете, Unfocused
VisualState
не имеет никакой анимации, относящейся к нему. Таким образом, если одна из этих кнопок не окажется в фокусе, она не отскочит. Это просто изменит цвет с красного на оранжевый в соответствии с MouseOver
VisualState
,
Я думаю, что это было бы хорошим чтением для вашего: MSDN Focus Overview
РЕДАКТИРОВАТЬ:
Объяснение для обсуждения в комментариях.
XAML:
<Window x:Class="Focus.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Button Content="Button 1" HorizontalAlignment="Center" Width="75" Margin="20" GotFocus="Button1_GotFocus"/>
<Button Content="Button 2" HorizontalAlignment="Center" Width="75" GotFocus="Button2_GotFocus"/>
</StackPanel>
</Window>
Code-Behind:
using System.Windows;
namespace Focus
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button1_GotFocus(object sender, RoutedEventArgs e)
{
MessageBox.Show("Button 1 Focused");
}
private void Button2_GotFocus(object sender, RoutedEventArgs e)
{
MessageBox.Show("Button 2 Focused");
}
}
}