简体   繁体   English

WinStore:在屏幕上和屏幕外滑动网格

[英]WinStore: Slide a Grid on- and off-screen

I've got an app that has a few nested Grids, like so: 我有一个带有一些嵌套网格的应用程序,如下所示:

<Grid x:Name="ContainerGrid">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="2*" />
        <ColumnDefinition Width="1*" />
    </Grid.ColumnDefinitions>
    <Grid Grid.Column="0">
        [main content here, including a button to show/hide the menu]
    </Grid>
    <Grid Grid.Column="1" x:Name="MenuGrid">
        <ColumnDefinition Width="1*" />
        <ColumnDefinition Width="0*" />
        <usercontrols:MyMenu Grid.Column="1" />
    </Grid>
</Grid>

I've got my UserControl (MyMenu) currently hidden off the right side of the screen via ColumnDefintion setting, but I don't feel like that's a good way to do it. 目前,我的UserControl(MyMenu)通过ColumnDefintion设置隐藏在屏幕的右侧,但是我觉得这不是一个好方法。

Add to that the idea that my main content should have a Button that, when clicked, will cause the MyMenu UserControl to slide in (or out) of the screen. 此外,我的主要内容应该具有一个Button,该按钮在单击时会导致MyMenu UserControl滑入(或滑出)屏幕。

I've noticed that I can't seem to animate GridLength properties (their Value properties are read-only), and I might be able to use a VisualStateManager to animate the Margin.Left of the MyMenu. 我注意到我似乎无法设置GridLength属性的动画(它们的Value属性是只读的),并且我可以使用VisualStateManager来设置MyMenu的Margin.Left的动画。 But that doesn't seem like the right way to do it. 但是,这似乎并不像做正确的方式。

I'd greatly appreciate any guidance on how to approach this task. 非常感谢您提供有关如何完成此任务的指导。

You can definitely use the Visual State Manager to start a storyboard. 您绝对可以使用Visual State Manager启动情节提要。 However, when it comes to animating stuff across a screen, TranslateTransform is far better suited than Margin . 但是,在跨屏幕动画时, TranslateTransformMargin更适合。

First, define the render transform on your control: 首先,在控件上定义渲染变换:

<usercontrols:MyMenu x:Name="MenuControl">
    <usercontrols:MyMenu.RenderTransform>
        <!-- Start off screen -->
        <TranslateTransform X=-1000/>
    </usercontrols:MyMenu.RenderTransform>
</usercontrols:MyMenu>

Then in your storyboard, target the X property of the transform. 然后,在情节提要中,定位转换的X属性。 The path is a little tricky: 路径有些棘手:

<Storyboard>
   <DoubleAnimation Storyboard.TargetName="MenuControl"
        Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X) "
        From="-1000"
        To="0"
        Duration="0:0:2"/>
</Storyboard>

Basically, you have to put the fact that the RenderTransform is a TranslateTransform as part of the property path. 基本上,您必须将RenderTransform TranslateTransform作为属性路径的一部分。

Finally, run the storyboard however you like, the Visual State Manager is certainly reasonable. 最后,运行您喜欢的情节提要,Visual State Manager当然是合理的。

The properties you mention you'd like to animate are associated with layout updates which means each change requires layout calculations from other elements in the visual tree which can be slow when we're in a context of 20-60fps animation. 您提到要设置动画的属性与布局更新相关联,这意味着每次更改都需要视觉树中其他元素的布局计算,这在20-60fps动画环境中可能会很慢。 That's why WinRT-XAML treats these differently and it requires marking an animation with the EnableDependentAnimation tag to enable it. 这就是WinRT-XAML区别对待这些原因的原因,它要求使用EnableDependentAnimation标记标记动画以将其启用。 What you typically should do in such cases instead is apply a RenderTransform to the element you'd like to slide, use a TranslateTransform to do the actual translation and have the animation target the transform's X or Y property. 在这种情况下,通常应该执行的操作是将RenderTransform应用于要滑动的元素,使用TranslateTransform进行实际的翻译,并使动画针对转换的XY属性。

Not sure if this is what you want but if you want an easy way to do a slide effect when clicking on a button there's that : 不知道这是否是您想要的,但是如果您想在单击按钮时想要一种简单的方法来进行幻灯片效果,那就是:

Create a button "slide_menu", add to that a timer with enable proprety as false. 创建一个按钮“ slide_menu”,并在其中添加一个启用属性为false的计时器。

Resize your window menu to whatever size you want at the minimum(when its hidden) and put the maximum size(width or height) into the code, here its 300. 将窗口菜单的大小调整为最小(隐藏时),然后将最大大小(宽度或高度)放入代码中,此处为300。

private void tm_Tick(object sender, EventArgs e) //the tick event of the timer
    {
        if (this.Height >= 300) // here is my windows that is 300 height when slided.
            this.tm.Enabled = false; // disables the timer when max size is reached.
        else
            this.Height += 12; //choose a value that fits you. (the more you add to it, the faster it will slide to the reach maximum point"
    }

    private void slide_dwn_Click(object sender, EventArgs e)
    {
        this.tm.Enabled = true; //enables the timer when clicking on the button
    }

You can also do it from an horizontal view, just change Height by Width in the code. 您也可以从水平视图中进行操作,只需在代码中将“高度乘宽度”更改即可。

Also dont forget to change the interval of the timer to 1 for a smooth effect, you can find it in the propreties of the timer in the design form. 同样不要忘记将定时器的间隔更改为1以获得平滑效果,您可以在设计表格的定时器属性中找到它。

Hope this helped. 希望这会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM