WPF动画 - 不要想用内容 [英] WPF Animation - Don't Want to use Content

查看:167
本文介绍了WPF动画 - 不要想用内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是从WPF动画新手一个问题的两个部分。首先,这里是我的code:

 公共无效AnimatePaneBox(ContentControl中的目的地,
                           UIElementCollection源)
{
    //创建一个名称范围为这个网页上
    //故事板可以使用。
    NameScope.SetNameScope(这一点,新名称范围());    帆布containerCanvas =新的Canvas();
    INT curInteration = 0;    的foreach(源FrameworkElement的元素)
    {
        curInteration ++;
        字符串iterationName =ITER+ curInteration.ToString();        GeneralTransform等转换;        尝试
        {
            //尝试获得变换对象。它可能是不可能的。
            //(例如,如果源或DEST不那么它停靠
            //将失败,我们不能动画)。
            等转换= element.TransformToVisual(目标);
        }
        赶上(InvalidOperationException异常E)
        {
            返回;
        }
        指向rootPoint = tranform.Transform(新点(0,0));        矩形sourceRelativeRect =新的矩形(
              rootPoint.X - (destination.ActualWidth / 2),
              rootPoint.Y - (destination.ActualHeight / 2),
              element.ActualWidth,element.ActualHeight);        RectangleGeometry myRectangleGeometry =新RectangleGeometry
              {矩形=新的Rect(0,0,0,0)};        //分配几何名称,以便
        //它可以由一个故事板有针对性。
        RegisterName(iterationName,myRectangleGeometry);        路径mypath中=新路径
        {
            填写=((Canvas)的元素)技术领域,
            StrokeThickness = 1,
            行程= Brushes.Black,
            数据= myRectangleGeometry
        };
        RectAnimation myRectAnimation =新RectAnimation
        {
            持续时间= TimeSpan.FromSeconds(1),
            FillBehavior = FillBehavior.Stop,
            AccelerationRatio = 1,
            //设置往返于动画的属性。
            从= sourceRelativeRect,
            为=新的Rect(0,0,0,0)
        };        //设置动画的目标rect属性
        //命名的对象的MyAnimatedRectangleGeometry。
        Storyboard.SetTargetName(myRectAnimation,iterationName);
        Storyboard.SetTargetProperty(myRectAnimation,
            新的PropertyPath(RectangleGeometry.RectProperty));        //创建一个故事板应用动画。
        故事板ellipseStoryboard =新的故事板();
        ellipseStoryboard.Children.Add(myRectAnimation);
        containerCanvas.Children.Add(mypath中);        //开始故事板路径负载时。
        myPath.Loaded + =((发件人,E)=> ellipseStoryboard.Begin(本));
    }    containerCanvas.Background = Brushes.Transparent;    destination.Content = containerCanvas;
}

这需要对象的列表(由 Dotway <一个href=\"http://public.bay.livefilestore.com/y1pBD-o5M4iNgOF3QaKH6z0eA07-0ic1Z1opIcGcSWamyshJqTmUF2H7KO1Ti-AqcGq-cEYg5jBEhttsmCD%5F-G98w/wpf9.jpg\"相对=nofollow>拉链面板)和动画箱子从他们移动到目的地。

它工作得很好,但要使它工作我必须覆盖目标的内容。我以后可以将其恢复,但我宁愿找到一种方法,使这项工作没有这样做。我试图创建的EventTrigger并使用BeginStoryboard对象,但是当我尝试,我没有看到任何动画的。

另外,我很想知道我怎么能做出这些动画会发生一次,而不是所有的一次。 (但是,这是次要的主要问题。)


解决方案

  1. 根据您所提供的code,有没有办法动画就没有内容更换。但是,你可以随时把两个控件在同一电网,为说...他们会占据相同的地方。一会是动画容器的占位符,而另一个 - 您的实际内容,你不想松动


  2. 相反在 myPath.Loaded + =(O,E)=&GT推出他们在一起的; ellipseStoryboard.Begin(本); 处理程序,由一个发射它们。 firstStoryboard.Completed + =(O,E)=&GT; nextStoryboard.Begin(本);


This is a two part question from a WPF animation newbie. First, here is my code:

public void AnimatePaneBox(ContentControl destination, 
                           UIElementCollection source)
{
    // Create a NameScope for this page so that
    // Storyboards can be used.
    NameScope.SetNameScope(this, new NameScope());

    Canvas containerCanvas = new Canvas();
    int curInteration = 0;

    foreach (FrameworkElement element in source)
    {
        curInteration++;
        string iterationName = "iter" + curInteration.ToString();

        GeneralTransform tranform;

        try
        {
            // Try to get a transform object.  It may not be possible.
            // (ie if the source or dest is not docked then it 
            // will fail and we cannot animate.)
            tranform = element.TransformToVisual(destination);
        }
        catch (InvalidOperationException e)
        {
            return;
        }


        Point rootPoint = tranform.Transform(new Point(0, 0));

        Rect sourceRelativeRect = new Rect(
              rootPoint.X - (destination.ActualWidth / 2),
              rootPoint.Y - (destination.ActualHeight / 2), 
              element.ActualWidth, element.ActualHeight);

        RectangleGeometry myRectangleGeometry = new RectangleGeometry 
              { Rect = new Rect(0, 0, 0, 0) };

        // Assign the geometry a name so that
        // it can be targeted by a Storyboard.
        RegisterName(iterationName, myRectangleGeometry);              

        Path myPath = new Path
        {
            Fill = ((Canvas)element).Background,
            StrokeThickness = 1,
            Stroke = Brushes.Black,
            Data = myRectangleGeometry
        };


        RectAnimation myRectAnimation = new RectAnimation
        {
            Duration = TimeSpan.FromSeconds(1),
            FillBehavior = FillBehavior.Stop,
            AccelerationRatio = 1,
            // Set the From and To properties of the animation.
            From = sourceRelativeRect,
            To = new Rect(0, 0, 0, 0)
        };

        // Set the animation to target the Rect property
        // of the object named "MyAnimatedRectangleGeometry."
        Storyboard.SetTargetName(myRectAnimation, iterationName);
        Storyboard.SetTargetProperty(myRectAnimation, 
            new PropertyPath(RectangleGeometry.RectProperty));

        // Create a storyboard to apply the animation.
        Storyboard ellipseStoryboard = new Storyboard();
        ellipseStoryboard.Children.Add(myRectAnimation);
        containerCanvas.Children.Add(myPath);

        // Start the storyboard when the Path loads.
        myPath.Loaded += ((sender, e) => ellipseStoryboard.Begin(this));
    }

    containerCanvas.Background = Brushes.Transparent;

    destination.Content = containerCanvas;
}

This takes a list of objects (from a Dotway Zipper Panel) and animates boxes moving from them to a destination.

It works just fine, but to make it work I have to overwrite the destination's content. I can restore it afterwards, but I would rather find a way to make this work without doing that. I have tried to create a EventTrigger and use the BeginStoryboard object, but when I try that I don't see any animation at all.

Also, I would love to know how I could make these animations happen one at a time instead of all at once. (But that is secondary to the main question.)

解决方案

  1. According to the code you've provided, there is no way to animate it without content replacement. But you can always put two controls in the same Grid, for say... They'll occupy the same place. One will be a placeholder for animation container, and another - your actual content you don't want to loose.

  2. Instead of launching them all together in myPath.Loaded += (o, e) => ellipseStoryboard.Begin(this); handler, launch them one by one. firstStoryboard.Completed += (o,e)=> nextStoryboard.Begin(this);

这篇关于WPF动画 - 不要想用内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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