none
WPF动画问题——如何使一个容器在动画中由自动宽度变为固定值 RRS feed

  • 问题

  • WPF动画问题——如何使一个容器在动画中由自动宽度变为固定值???

    我建立的一个GRID,希望其动画中Width由Auto变为100,应该如何实现?


    • 已编辑 MINE1532 2012年3月16日 14:32
    2012年3月16日 13:01

答案

  •     HI:

        DoubleAnimation 有 From 和 To 两个属性,如果动画需要应用的属性已经有值,则可以只指定 To, 如 To = 100。由于你的 Grid 的宽度是 Auto 的,所以如果只定义 To 则会报异常,你现在遇到的是这个问题么?

        你需要同时指定 From 和 To。FrameworkElement 有一个 ActualWidth 属性,用来表示一个 UI 元素呈现的实际宽度。所以你的 From 因该是这个值。而同时 From 是一个依赖项属性,所以你可以用绑定的方式来找到这个值,我假定了一个 Border,不指定其宽度,以此模仿你的 Auto,示例代码如下:

    <Window x:Class="Client.MainWindow" Title="MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <Grid Width="500" Height="500">
            <Border x:Name="border" x:FieldModifier="private" Background="LightBlue" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="30">
                <Border.Triggers>
                    <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                        <BeginStoryboard>
                            <Storyboard Storyboard.TargetName="border" Storyboard.TargetProperty="Width">
                                <DoubleAnimation Duration="0:0:4" From="{Binding ActualWidth, ElementName=border}" To="100"></DoubleAnimation>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </Border.Triggers>
            </Border>
        </Grid>
        
    </Window>

        你也可以在后台写:

            // border 加载完成后对其宽度应用动画
            private void border_Loaded(object sender, RoutedEventArgs e)
            {
                Border border = sender as Border;
                // 建立 DoubleAnimation 应用于 border.Width
                DoubleAnimation animation = new DoubleAnimation();
                animation.Duration = new Duration(TimeSpan.FromSeconds(4));
                animation.SetValue(Storyboard.TargetProperty, border);
                animation.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("Width"));       
                animation.From = border.ActualWidth;
                animation.To = 100;
                // 创建演示面板
                Storyboard storyboard = new Storyboard();
                storyboard.Children.Add(animation);
                storyboard.Begin();
            }

       动画结束后 Width 已经被时钟控制,而且也有了值,已经不是 Auto, 如果你要使宽度再次变为 Auto,还需要另行处理。

       希望对你有用。

                                                                         Bean


    • 已编辑 兔子不乖 2012年3月16日 16:41 ActualWidth属性来源于FrameworkElement,而不是UIElement,修正这个错误
    • 已建议为答案 兔子不乖 2012年3月16日 16:48
    • 取消建议作为答案 兔子不乖 2012年3月17日 14:08
    • 已标记为答案 MINE1532 2012年3月17日 14:22
    2012年3月16日 16:36