Когда мне кажется, что я понимаю VisualStateManager
, что-то доказывает, что я ошибаюсь.
Я использую WPF 4 и пытаюсь просто увеличить элемент, наведенный на , и уменьшите его при отпускании мыши. Я решил, что нужно просто определить каждое состояние в VisualStateGroup
, а затем указать VisualTransition
с помощью GeneratedDuration
:
<Border x:Name="PART_Root" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" RenderTransformOrigin="0.5,0.5">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:1"/>
</VisualStateGroup.Transitions>
<VisualState Name="Normal"/>
<VisualState Name="MouseOver">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleX" To="1.5" Duration="0"/>
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleY" To="1.5" Duration="0"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border.RenderTransform>
<ScaleTransform x:Name="scaleTransform" ScaleX="1" ScaleY="1"/>
</Border.RenderTransform>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
Поскольку у меня есть универсальная VisualTransition
с GeneratedDuration
, я ожидал, что VSM будет генерировать промежуточные анимации. То есть при наведении указателя мыши на элемент управления следует анимировать свойства ScaleTransform
от 1 до 1,5 в течение 1 секунды. То же самое с отключением мыши. Вместо этого происходит задержка в 1 секунду, а затем свойства ScaleTransform
мгновенно привязываются к 1,5 или обратно к 1.
Если я вручную задаю переходы следующим образом, я получаю желаемое поведение:
<VisualStateGroup.Transitions>
<VisualTransition From="Normal" To="MouseOver">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleX" To="1.5" Duration="{StaticResource MouseEnterDuration}"/>
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleY" To="1.5" Duration="{StaticResource MouseEnterDuration}"/>
</Storyboard>
</VisualTransition>
<VisualTransition From="MouseOver" To="Normal">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleX" To="1" Duration="{StaticResource MouseLeaveDuration}"/>
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleY" To="1" Duration="{StaticResource MouseLeaveDuration}"/>
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
Но почему я должен это сделать? Я думал, что весь смысл сгенерированных переходов заключается в том, что переход, вы знаете, будет сгенерирован. Что я здесь не понимаю?
ОБНОВЛЕНИЕ : Согласно ответу Рика, Blend генерирует то, что работает . Таким образом, работая в обратном направлении, я определил, что на самом деле я ссылаюсь на ScaleTransform
напрямую, а не через UIElement
, который его содержит. Я изменил свой XAML на следующий, и он работает, как ожидалось:
<Border x:Name="PART_Root" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" RenderTransformOrigin="0.5,0.5">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition From="Normal" To="MouseOver" GeneratedDuration="{StaticResource MouseEnterDuration}"/>
<VisualTransition From="MouseOver" To="Normal" GeneratedDuration="{StaticResource MouseLeaveDuration}"/>
</VisualStateGroup.Transitions>
<VisualState Name="Normal"/>
<VisualState Name="MouseOver">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="PART_Root" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)" To="{StaticResource MouseOverScale}" Duration="0"/>
<DoubleAnimation Storyboard.TargetName="PART_Root" Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)" To="{StaticResource MouseOverScale}" Duration="0"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border.RenderTransform>
<ScaleTransform/>
</Border.RenderTransform>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
Выглядит нелепо (и очевидная ошибка), но работает.
Спасибо