wpf use VisualStateManager to change Visibility
Asked Answered
L

2

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?

Lovelorn answered 28/5, 2015 at 14:3 Comment(4)
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.Yalta
The only difference I can see is that I'm using {x:Static Visibility.Visible} as the Value, instead of just Visible.Yalta
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.5Lovelorn
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.Lovelorn
Y
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;
Yalta answered 28/5, 2015 at 15:58 Comment(1)
you were right, I missed a few {x:Static Visibility.Visible} in my wpf code. it works now, thanks!Lovelorn
V
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.

Votive answered 28/5, 2015 at 14:14 Comment(1)
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.Lovelorn

© 2022 - 2024 — McMap. All rights reserved.