4
votes

I'm working on transitioning some code from silverlight to WPF, and my VisualStates are not working correctly.

I am using visualstatemanager to control the visibility of some text fields. I am not using any transitions to animate the change, I just want the fields to be collapsed in one state, then visible in another.

Xaml from silverlight:

<VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="LostPasswordStates">
            <VisualState x:Name="LostPassword_Start">
                <Storyboard>

                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="lbl_UserName" Storyboard.TargetProperty="(UIElement.Visibility)">
                        <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Visible" />
                    </ObjectAnimationUsingKeyFrames>

                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="txt_UserName" Storyboard.TargetProperty="(UIElement.Visibility)">
                        <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Visible" />
                    </ObjectAnimationUsingKeyFrames>

                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="txt_UserName" Storyboard.TargetProperty="(TextBox.IsReadOnly)">
                        <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="False" />
                    </ObjectAnimationUsingKeyFrames>

                </Storyboard>
            </VisualState>
            <VisualState x:Name="LostPassword_Success">
                <Storyboard>

                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="lbl_UserName" Storyboard.TargetProperty="(UIElement.Visibility)">
                        <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Collapsed" />
                    </ObjectAnimationUsingKeyFrames>

                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="txt_UserName" Storyboard.TargetProperty="(UIElement.Visibility)">
                        <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Collapsed" />
                    </ObjectAnimationUsingKeyFrames>

                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="btn_Reset" Storyboard.TargetProperty="(UIElement.Visibility)">
                        <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Collapsed" />
                    </ObjectAnimationUsingKeyFrames>

                </Storyboard>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>

I get the following exception :

An unhandled exception of type 'System.Windows.Media.Animation.AnimationException' occurred in PresentationCore.dll

Additional information: Cannot animate the 'Visibility' property on a 'System.Windows.Controls.TextBox' using a 'System.Windows.Media.Animation.ObjectAnimationUsingKeyFrames'. For details see the inner exception.

So my question to you is:

If I can't use a System.Windows.Media.Animation.ObjectAnimationUsingKeyFrames for this, what should I be using?

2
Which version of WPF? I've got a virtually identical storyboard animating the UIElement.Visibility property on a Border which works fine in 4.0 and 4.5.Richard Deeming
The only difference I can see is that I'm using {x:Static Visibility.Visible} as the Value, instead of just Visible.Richard Deeming
you're right, I did change the the values to the {x:Static Visibility.Collapsed} format in my wpf code. (I copied the text above stright from the silverlight version) Also, I'm using .net 4.5Shaboboo
UIElement.Visibility seems to work on some elements and not others. Label for example doesn't seem to have an issue, but Textbox and buttons do have the issue.Shaboboo

2 Answers

7
votes

This works for me, using .NET 4.5:

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="LostPasswordStates">
        <VisualState x:Name="LostPassword_Start">
            <Storyboard>

                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="lbl_UserName" Storyboard.TargetProperty="(UIElement.Visibility)">
                    <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Visible}" />
                </ObjectAnimationUsingKeyFrames>

                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="txt_UserName" Storyboard.TargetProperty="(UIElement.Visibility)">
                    <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Visible}" />
                </ObjectAnimationUsingKeyFrames>

                <BooleanAnimationUsingKeyFrames Storyboard.TargetName="txt_UserName" Storyboard.TargetProperty="(TextBox.IsReadOnly)">
                    <DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="False" />
                </BooleanAnimationUsingKeyFrames>

            </Storyboard>
        </VisualState>
        <VisualState x:Name="LostPassword_Success">
            <Storyboard>

                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="lbl_UserName" Storyboard.TargetProperty="(UIElement.Visibility)">
                    <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Collapsed}" />
                </ObjectAnimationUsingKeyFrames>

                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="txt_UserName" Storyboard.TargetProperty="(UIElement.Visibility)">
                    <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Collapsed}" />
                </ObjectAnimationUsingKeyFrames>

                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="btn_Reset" Storyboard.TargetProperty="(UIElement.Visibility)">
                    <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Collapsed}" />
                </ObjectAnimationUsingKeyFrames>

            </Storyboard>
        </VisualState>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

There are two changes to your current code:

  • Instead of "Collapsed" and "Visible", the Value is set to "{x:Static Visibility.Collapsed}" and "{x:Static Visibility.Visible}";
  • The IsReadOnly property uses a BooleanAnimationUsingKeyFrames instead of an ObjectAnimationUsingKeyFrames;
0
votes

You can only animate properties of numeric types (double). Visibility can not be animated because it is enum an there is no way to animate this meaningfull. If you want to fadeout something you can use the opacity property.