Просто, когда мне кажется, что я понимаю 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>
Кажется смешным (и очевидная ошибка), но это работает.
Спасибо