如何基于控制的特性(顶/制表位)设置WPF动画的BeginTime [英] How to set WPF animation BeginTime based on properties (Top/Tabstop) of the control

查看:331
本文介绍了如何基于控制的特性(顶/制表位)设置WPF动画的BeginTime的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在垂直堆叠面板一系列按钮,类似于DVR的菜单看起来像一个WPF应用程序。我想通了如何使其中加载的每个新的菜单页面时,按钮/控制所有{unfade,秋天,去模糊,不管}成的存在,这是好的,但有点太均匀的动画。我真正喜欢的是让每个按钮的动画开始在一个稍微不同的时间,根据其位置或制表位属性。因此,例如顶部的按钮将开始第一,那么接下来,等等,直到下按钮,也许一个50毫秒的每个之间延迟启动,(但使得第一人们不必注:第二个前完成开始)。当然,我可以只让不同的动画为每个按钮,但我希​​望有一个稍微更优雅的解决方案。我不明白的方式给任何控件的属性装载到故事板的BeginTime。有只使用XAML做一个好办法,还是会像这样需要codebehind?如果是后者是可以包成一个行为,并能够加载声明后来,还是我坚持势在必行code下去吗?

I've got a WPF app that has a series of buttons in a vertical stack panel, similar to what a DVR menu would look like. I figured out how to make an animation where when each new menu page is loaded, the buttons/controls all {unfade, fall, deblur, whatever} into existence, which is nice but a little too uniform. What I'd really like is to have that animation start on each button at a slightly different time, based on its location or tabstop properties. So for instance the top button would be the first to begin, then the next, etc, until the bottom button, maybe a 50 ms delay between each start, (but such that the first one doesn't have to finish before the 2nd one starts). Sure I could just make different Animation for each button, but I'm hoping for a slightly more elegant solution. I don't see a way to load any of the control's properties into the BeginTime of the storyboard. Is there a good way to do using only XAML, or will something like this require codebehind? If the latter, is it possible to package that into a Behavior and be able to load that declaratively later on, or am I stuck with imperative code forever?

推荐答案

简短的答案是否定的(据我所知),你不能这样做的究竟的你正在使用XAML只是要求,这里是为什么。

The short answer is no (to the best of my knowledge), you cannot do exactly what you are asking with XAML only, and here is why.

虽然有很多方法可以做到在WPF的动画,使用XAML动画的唯一途径是通过故事板。跨元素共享一个故事板的唯一方法是通过在资源打包,比如一个风格的ControlTemplate或DataTemplate中。然而,为了使用一个故事板作为一个资源它必须是可冻结,这意味着它可以不包含任何数据绑定将需要动画的BeginTime与动画的目标的一个属性相关联的前pressions(如在TabIndex的或按钮的其他一些属性)。即使你能够以某种方式动画的的BeginTime结合到按钮的属性,您仍需要使用codebehind写ValueConverter到Button属性值转换为时间跨度值(所需的50毫秒的累积延迟)。

While there are many ways to do animations in WPF, the only way to animate with XAML is by using Storyboards. The only way to share a Storyboard across elements is by packaging it in a Resource such as a Style, ControlTemplate, or DataTemplate. However, in order to use a Storyboard as a Resource it must be Freezable, which means it cannot contain any data binding expressions that would be required to associate the animation BeginTime with a property of the target of the animation (such as the TabIndex or some other property of your Buttons). Even if you could somehow bind the BeginTime of an animation to a property of the Button, you would still need to use codebehind to write a ValueConverter to convert the Button property value to a TimeSpan value (your desired 50ms cumulative delay).

因此​​,为了做的究竟的你想要什么,你需要使用codebehind如本例所示:

So in order to do exactly what you want, you would need to use codebehind as shown in this example:

XAML:

<StackPanel HorizontalAlignment="Left" Width="100" Loaded="StackPanel_Loaded">
    <Button Content="Button1"/>
    <Button Content="Button2"/>
    <Button Content="Button3"/>
    <Button Content="Button4"/>
    <Button Content="Button5"/>
    <Button Content="Button6"/>
    <Button Content="Button7"/>
    <Button Content="Button8"/>
    <Button Content="Button9"/>
    <Button Content="Button10"/>
</StackPanel>

codebehind:

Codebehind:

private void StackPanel_Loaded(object sender, RoutedEventArgs e)
{
    StackPanel stackPanel = sender as StackPanel;
    DoubleAnimation fadeInAnimation = new DoubleAnimation(1.0, new Duration(TimeSpan.FromMilliseconds(200)));
    for (int i = 0; i < stackPanel.Children.Count; i++)
    {
        fadeInAnimation.BeginTime = TimeSpan.FromMilliseconds(i * 50);
        stackPanel.Children[i].Opacity = 0.0;
        stackPanel.Children[i].BeginAnimation(UIElement.OpacityProperty, (AnimationTimeline)fadeInAnimation.GetAsFrozen());
    }
}

话虽这么说,有办法来近似只使用XAML您所需的行为。例如,您可以覆盖有一个LinearGradientBrush OpacityMask的StackPanel中和动画,与这样一个情节提要:

That being said, there are ways to approximate your desired behavior using XAML only. For example, you could overlay the StackPanel with a LinearGradientBrush OpacityMask and animate that with a single Storyboard like this:

XAML:

<StackPanel HorizontalAlignment="Left" Width="100">
    <StackPanel.OpacityMask>
        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
            <GradientStop Color="Black"/>
            <GradientStop x:Name="TransparentGradient" Color="Transparent"/>
        </LinearGradientBrush>
    </StackPanel.OpacityMask>
    <StackPanel.Triggers>
        <EventTrigger RoutedEvent="Loaded">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation
                        Storyboard.TargetName="TransparentGradient" Storyboard.TargetProperty="Offset"
                        To="1.0" Duration="0:0:0.5"/>
                    <ColorAnimation
                        Storyboard.TargetName="TransparentGradient" Storyboard.TargetProperty="Color"
                        To="Black" BeginTime="0:0:0.5" Duration="0:0:0.5"/>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </StackPanel.Triggers>
    <Button Content="Button1"/>
    <Button Content="Button2"/>
    <Button Content="Button3"/>
    <Button Content="Button4"/>
    <Button Content="Button5"/>
    <Button Content="Button6"/>
    <Button Content="Button7"/>
    <Button Content="Button8"/>
    <Button Content="Button9"/>
    <Button Content="Button10"/>
</StackPanel>

这会给你一个很好的自上而下淡入其他影响也有可能出现一个小创意,而是忠告:尽量避免花费太多时间寻找复杂的XAML解决方案时,您可以acheive预期的效果与code的只有几行。

That would give you a nice top to bottom fade in. Other effects could also be possible with a little creativity, but a word of advice: try to avoid spending too much time finding complex XAML solutions when you can acheive the desired effect with just a few lines of code.

编程快乐!

这篇关于如何基于控制的特性(顶/制表位)设置WPF动画的BeginTime的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆