WPF使用VisualStateManager更改可见性

6

我正在将一些代码从Silverlight转换到WPF,但我的VisualStates没有正常工作。

我使用VisualStateManager来控制一些文本字段的可见性。我没有使用任何过渡来动画改变,我只想在一个状态下将字段折叠起来,然后在另一个状态下显示出来。

Silverlight中的Xaml:

<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>

我遇到了以下异常:

未处理的类型为 'System.Windows.Media.Animation.AnimationException' 的异常发生在 PresentationCore.dll 中。

更多信息:无法使用 'System.Windows.Media.Animation.ObjectAnimationUsingKeyFrames' 在 'System.Windows.Controls.TextBox' 上动画化 'Visibility' 属性。请参见内部异常以了解详情。

所以我的问题是:

如果我不能使用 System.Windows.Media.Animation.ObjectAnimationUsingKeyFrames,在这种情况下应该使用什么?


哪个版本的WPF?我有一个几乎相同的故事板,可以在4.0和4.5上很好地动画化Border上的UIElement.Visibility属性。 - Richard Deeming
2
我唯一能看到的区别是,我使用{x:Static Visibility.Visible}作为Value,而不仅仅是Visible - Richard Deeming
你说得对,我确实在我的WPF代码中将值更改为{x:Static Visibility.Collapsed}格式。 (我直接从Silverlight版本复制了上面的文本) 另外,我正在使用.NET 4.5。 - Shaboboo
1
UIElement.Visibility 似乎对某些元素有效,而对其他元素无效。例如,Label 看起来没有问题,但 Textbox 和按钮却有问题。 - Shaboboo
2个回答

8

这对我来说可行,使用 .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>

您当前的代码有两个更改:

  • "Collapsed""Visible"替换为"{x:Static Visibility.Collapsed}""{x:Static Visibility.Visible}";
  • IsReadOnly属性使用BooleanAnimationUsingKeyFrames而不是ObjectAnimationUsingKeyFrames

你说得对,我的WPF代码中确实漏了一些{x:Static Visibility.Visible}。 现在它已经能够正常工作了,谢谢! - Shaboboo

0

您只能对数字类型(double)的属性进行动画处理。可见性无法进行动画处理,因为它是枚举类型,没有办法对其进行有意义的动画处理。 如果您想要淡出某些内容,可以使用不透明度属性。


我只想让它在一个瞬间可见,然后下一刻折叠起来,我根本不需要对其进行动画处理。对于这个,我是否应该使用视觉状态管理器?在我的Silverlight代码中,我使用了视觉状态管理器,并且我希望尽可能多地重用它。我知道我可以通过编码实现相同的结果。 - Shaboboo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接