6

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?

Shaboboo
  • 1,347
  • 1
  • 16
  • 35
  • 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 May 28 '15 at 14:39
  • 2
    The only difference I can see is that I'm using `{x:Static Visibility.Visible}` as the `Value`, instead of just `Visible`. – Richard Deeming May 28 '15 at 14:41
  • 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.5 – Shaboboo May 28 '15 at 14:44
  • 1
    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 May 28 '15 at 14:49

2 Answers2

8

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;
Richard Deeming
  • 29,830
  • 10
  • 79
  • 151
0

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.

Rene Niediek
  • 147
  • 9
  • I just want it to be visible one moment and collapsed the next, I don't need to animate it at all. Should I even be using visualstatemanager for this? I used the visual state manager in my silverlight code, and I want to re-use as much of it as I can. I know I can achieve the same results in code behind. – Shaboboo May 28 '15 at 14:47