When I think I understand VisualStateManager , something proves that I'm wrong.
I am using WPF 4 and I am trying to simply enlarge an element with the mouse and compress it when leaving the mouse. I decided that I would just define each state in a VisualStateGroup , and then specify VisualTransition with 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>
Since I have catch-all VisualTransition with GeneratedDuration , I expected VSM to generate intermediate animations. That is, the mouse over the control should animate the properties of the ScaleTransform from 1 to 1.5 for 1 second. The same with washing. Instead, there is a delay of 1 second, and then the ScaleTransform properties instantly snap to 1.5 or vice versa to 1.
If I manually specify the transitions as follows, I get the desired behavior:
<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>
But why should I do this? I thought that the whole point of the generated transitions was that the transition, as you know, will be generated. What i don't understand here?
UPDATE . According to the answers, Rika Blend generates what works. So, working backwards, I decided that it was really a fact that I only refer to ScaleTransform , and not through the UIElement that contains it. I changed my XAML to the following and it works as expected:
<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>
Seems funny (and an obvious mistake), but it works.
thanks
animation wpf transitions visualstatemanager
cantloginfromwork
source share