我应该使用哪些布局元素来实现带有动画过渡的子菜单

Which layout elements should I use to implement a submenu with an animation transition

我对这个 WinRT 和 XAML 东西还很陌生,不确定如何实现这个目标。对于我的页面布局,我基本上有 2 行。第一行代表我的(静态)基本菜单,带有一些按钮和图片(大约 130 高度)。屏幕的其余部分应该用于显示内容。像这样:

screen layout

现在,当用户单击主菜单按钮时,子菜单 "filter settings" 应该会随着动画向下移动。主要内容也响应此事件并相应移动("filter settings" 不应覆盖主要内容)。

我目前定义此布局的想法是使用一个包含 3 行和 2 个框架的网格。当没有过滤器被激活时,我使用 rowspan 让我的主要内容跨越整个区域。当识别到单击事件时,我将包含主要内容 (ModuleContentFrame) 的框架的行数更改为 2,并将其行跨度更改为 1。然后我将过滤页面加载到框架 ModuleFadeInFrame。

<Grid>
<Grid.RowDefinitions>
    <RowDefinition Height="130"/>
    <RowDefinition Height="1*"/>
    <RowDefinition Height="2*"/>
</Grid.RowDefinitions>

<Frame
    x:Name="ModuleFadeInFrame"
    Grid.Row="1"/>

<Frame
    x:Name="ModuleContentFrame"
    Grid.Row="1"
    Grid.RowSpan="2"/>

</Grid>

我的问题是:这个内部有网格和框架的布局定义是否适合解决这个问题?如何在显示子菜单时实现 "moving" 动画。我用 Storyboard 尝试了这个,但主要内容只是 "jumping" 到第 2 行

<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ModuleContentFrame"
                               Storyboard.TargetProperty="(Grid.Row)">
                <DiscreteObjectKeyFrame KeyTime="1" Value="2" />
</ObjectAnimationUsingKeyFrames>

您无法真正为网格设置动画 row/col/etc... 更改。此外,任何会导致布局更改的动画都是依赖动画 - 并且性能不佳。我会做的是这样的:

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:Interactivity="using:Microsoft.Xaml.Interactivity" xmlns:Core="using:Microsoft.Xaml.Interactions.Core"
    x:Class="App1.MainPage"
    mc:Ignorable="d">
    <Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="MenuState">
                <VisualStateGroup.Transitions>
                    <VisualTransition GeneratedDuration="0:0:0.3">
                        <VisualTransition.GeneratedEasingFunction>
                            <ExponentialEase EasingMode="EaseInOut"/>
                        </VisualTransition.GeneratedEasingFunction>
                    </VisualTransition>
                </VisualStateGroup.Transitions>
                <VisualState x:Name="ClosedState"/>
                <VisualState x:Name="OpenState">
                    <Storyboard>
                        <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="grid" d:IsOptimized="True"/>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <Grid>
            <Grid Margin="0,50,0,0" Background="Black">
                <TextBlock>
                    Long text blablabla
                </TextBlock>
            </Grid>
            <Grid x:Name="grid" Margin="0,50,0,0" Height="50" VerticalAlignment="Top" Background="#77ffff00">
                <Grid.RenderTransform>
                    <CompositeTransform TranslateY="-50"/>
                </Grid.RenderTransform>
                <Button Content="Close" >
                    <Interactivity:Interaction.Behaviors>
                        <Core:EventTriggerBehavior EventName="Click">
                            <Core:GoToStateAction StateName="ClosedState"/>
                        </Core:EventTriggerBehavior>
                    </Interactivity:Interaction.Behaviors>
                </Button>
            </Grid>
            <Grid Margin="0,0,0,0" Height="50" VerticalAlignment="Top" Background="Red">
                <Button Content="Open" >
                    <Interactivity:Interaction.Behaviors>
                        <Core:EventTriggerBehavior EventName="Click">
                            <Core:GoToStateAction StateName="OpenState"/>
                        </Core:EventTriggerBehavior>
                    </Interactivity:Interaction.Behaviors>
                </Button>
            </Grid>
        </Grid>
    </Grid>
</Page>

这样就不会改变布局,因为您的子菜单最终会位于内容之上。

如果你真的坚持'not obscuring content'方式

您可以在内容之前使用 Height="0" 设置子菜单,并使用 DoubleAnimation 设置元素高度的动画。如果这样做,则必须将 EnableDependentAnimation 设置为 true。

更多信息:https://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.ui.xaml.media.animation.pointanimation.enabledependentanimation.aspx

谢谢你 Tamás,你帮了我很多,让我得到了解决方案。我现在这样做如下:

此代码进入每个子菜单的 edit:UserControl。在主页上,我只需要处理我的 Button 单击事件并调用适当的动画。下一步是按照您的建议熟悉 Blend :-)

我将你的 post 标记为答案,因为它对我找到解决方案最有帮助

    <Grid x:Name="maingrid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" >
    <Grid.RenderTransform>
        <CompositeTransform TranslateY="-360"/>
    </Grid.RenderTransform>

    <Grid.Resources>
        <Storyboard x:Name="myStoryboardOpen">
            <DoubleAnimation Duration="0:0:0.3" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" 
                             Storyboard.TargetName="maingrid" 
                             d:IsOptimized="True"/>
        </Storyboard>
        <Storyboard x:Name="myStoryboardClose">
            <DoubleAnimation Duration="0:0:0.3" To="-360" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" 
                             Storyboard.TargetName="maingrid" 
                             d:IsOptimized="True"/>
        </Storyboard>
    </Grid.Resources>