2

我正在尝试为控件设置动画,以便将其可见性设置为可见,然后将不透明度从 0 设置为 1

但是什么也没发生,然后在 1 秒后,控件显示为 1 的不透明度...我看不到我做错了什么

这是我尝试过的代码

<Grid x:Name="layout_root" Margin="10">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="Filtering">
            <VisualStateGroup.Transitions>
                <VisualTransition GeneratedDuration="0:0:1">
                    <VisualTransition.GeneratedEasingFunction>
                        <ElasticEase EasingMode="EaseInOut"/>
                    </VisualTransition.GeneratedEasingFunction>
                </VisualTransition>
            </VisualStateGroup.Transitions>

            <VisualState x:Name="Disabled"/>
            <VisualState x:Name="Enabled">
                <Storyboard>
                    <ObjectAnimationUsingKeyFrames BeginTime="0:0:0" Duration="0:0:0" Storyboard.TargetName="filter_control" Storyboard.TargetProperty="(UIElement.Visibility)">
                        <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
                    </ObjectAnimationUsingKeyFrames>
                    <DoubleAnimation Storyboard.TargetName="filter_control" Storyboard.TargetProperty="(UIElement.Opacity)" To="1"/>
                </Storyboard>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>

    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition/>
    </Grid.RowDefinitions>

    <TextBox x:Name="filter_control" Margin="0,0,0,10" Text="Filtering" Visibility="Collapsed" Opacity="0"/>

    <ListView Grid.Row="1" ItemsSource="{Binding Posts}">
        <ListView.View>
            <GridView>
                <GridViewColumn Width="100" Header="Date" DisplayMemberBinding="{Binding Date, StringFormat={}{0:dd/MM/yyyy}}"/>
                <GridViewColumn Width="100" Header="Text" DisplayMemberBinding="{Binding Text}"/>
                <GridViewColumn Width="100" Header="Value" DisplayMemberBinding="{Binding Value, StringFormat=F2}"/>
            </GridView>
        </ListView.View>
    </ListView>

    <Button Grid.Row="1" Content="v" FontFamily="Marlett" FontSize="14" VerticalAlignment="Top" HorizontalAlignment="Left" Click="ShowFilterClick"/>
</Grid>
4

2 回答 2

3

至于你做错了什么或为什么你看到你看到的行为的问题:启用状态的故事板是 VSM 在 VSGroup处于该状态时使用的故事板。但是,您为组指定一个转换故事板,并且 VSM在状态之间转换时应用它。因此,当您将 VSGroup 置于启用状态时,VSM 首先播放转换情节提要,然后使用您为启用状态指定的稳态情节提要。过渡情节提要为 1 秒,这就是为什么您会看到 1 秒延迟,然后是爆音。

像下面这样的东西可能是你想要的。请注意,过渡情节提要执行您想要的动作/动画,状态情节提要仅说明动画属性应保持的最终值。此外,我将缓动函数应用于双动画而不是整个 VisualTransition——尝试使用缓动函数插入 Visibility 是没有意义的。

<VisualStateGroup x:Name="Filtering">
    <VisualStateGroup.Transitions>
        <VisualTransition From="Disabled" To="Enabled" GeneratedDuration="0:0:1">
            <Storyboard>
               <ObjectAnimationUsingKeyFrames Duration="0:0:0" Storyboard.TargetName="filter_control" Storyboard.TargetProperty="(UIElement.Visibility)">
                   <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
               </ObjectAnimationUsingKeyFrames>
               <DoubleAnimation Duration="0:0:1" Storyboard.TargetName="filter_control" Storyboard.TargetProperty="(UIElement.Opacity)" To="1">
                  <DoubleAnimation.EasingFunction>
                     <ElasticEase EasingMode="EaseInOut"/>
                  </DoubleAnimation.EasingFunction>
               </DoubleAnimation>
           </Storyboard>
       </VisualTransition>
       <!-- you could also have a transition from Enabled to Disabled -->
    </VisualStateGroup.Transitions>

    <VisualState x:Name="Disabled">
            <Storyboard>
               <ObjectAnimationUsingKeyFrames Duration="0:0:0" Storyboard.TargetName="filter_control" Storyboard.TargetProperty="(UIElement.Visibility)">
                   <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Collapsed}"/>
               </ObjectAnimationUsingKeyFrames>
               <DoubleAnimation Duration="0:0:0" Storyboard.TargetName="filter_control" Storyboard.TargetProperty="(UIElement.Opacity)" To="0"/>
           </Storyboard>
    </VisualState>
    <VisualState x:Name="Enabled">
            <Storyboard>
               <ObjectAnimationUsingKeyFrames Duration="0:0:0" Storyboard.TargetName="filter_control" Storyboard.TargetProperty="(UIElement.Visibility)">
                   <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
               </ObjectAnimationUsingKeyFrames>
               <DoubleAnimation Duration="0:0:0" Storyboard.TargetName="filter_control" Storyboard.TargetProperty="(UIElement.Opacity)" To="1"/>
           </Storyboard>
    </VisualState>
</VisualStateGroup>
于 2012-09-06T17:28:01.800 回答
1

Visibility 枚举不是固有的动画属性。通常只有数字属性是真正可动画的,因为 WPF 可以填充关键帧之间的空间。例如,它知道介于 0 和 1 之间的不透明度是 0.5。它根据当前时间知道每个可能的值。

如果您从 Visibility.Collapsed 到 Visibility.Visible 的动画超过 1 秒,它不知道在 0.5 秒标记处或中间的任何其他时间点做什么。它只知道您正在将枚举从 1 个值更改为另一个值。如果你的过渡时间是 1 秒,它会等到那一秒结束然后改变值,所以你永远看不到不透明动画的发生。

您可以尝试使用 FluidLayout。您可以这样启用它:

<VisualStateGroup x:Name="Filtering" ei:ExtendedVisualStateManager.UseFluidLayout="True">

您还可以使用 Blend UI 中的切换开关来启用它。

FluidLayout 为您动画布局更改。折叠或展开元素会影响布局,因此它可以自动为这些布局更改设置动画。

于 2012-09-06T14:53:14.170 回答