WPF: Animating TranslateTransform from code

前端 未结 4 864
梦如初夏
梦如初夏 2021-02-04 02:17

I have a WPF canvas on which I\'m dynamically creating objects from code. These objects are being transformed by setting the RenderTransform property, and an animation needs to

相关标签:
4条回答
  • 2021-02-04 02:41

    No need to register the transform or add the storyboard to the resource collection if the target is the FrameworkElement you want to animate. You can use Blend to generate the PropertyPath syntax.

    frameworkElement.RenderTransform = new TransformGroup
            {
                Children =
                {
                    new ScaleTransform(),
                    new SkewTransform(),
                    new RotateTransform(),
                    translate
                }
            };
    translate.X = 100.0;
    var animation = new DoubleAnimation(0.0, TimeSpan.FromSeconds(1));
    var sb = new Storyboard();            
    sb.Children.Add(animation);
    Storyboard.SetTarget(animation, frameworkElement);
    Storyboard.SetTargetProperty(animation, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"));
    sb.Begin();
    
    0 讨论(0)
  • 2021-02-04 02:48

    Seems that after a bit of Googling I solved the problem myself. Many thanks to MSDN documentation and a post in MSDN forums by Antares19.

    In summary:

    • For a Freezable object (like TranslateTransform) to be targetable by an Storyboard, it must have a registered name. This can be done by calling FrameworkElement.RegisterName(..).

    • I added the Storyboard object to the ResourceDictionary of the same Framework element to which I registered the TranslateTransform. This can be done by calling ResourceDictionary.Add(..)

    Here's the updated code, which now animates nicely, and registers/deregisters the added resources:

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    
    namespace AnimationCompletedTest {
    
        public partial class MainWindow : Window {
    
            Canvas panel;
            public MainWindow() {
                InitializeComponent();
                MouseDown += DoDynamicAnimation;
    
                Content = panel = new Canvas();
            }
    
            void DoDynamicAnimation(object sender, MouseButtonEventArgs args) {
                for (int i = 0; i < 12; ++i) {
                    var e = new Ellipse { Width = 16, Height = 16, Fill = SystemColors.HighlightBrush };
                    Canvas.SetLeft(e, Mouse.GetPosition(this).X);
                    Canvas.SetTop(e, Mouse.GetPosition(this).Y);
    
                    var tg = new TransformGroup();
                    var translation = new TranslateTransform(30, 0);
                    var translationName = "myTranslation" + translation.GetHashCode();
                    RegisterName(translationName, translation);
                    tg.Children.Add(translation);
                    tg.Children.Add(new RotateTransform(i * 30));
                    e.RenderTransform = tg;
    
                    panel.Children.Add(e);
    
                    var anim = new DoubleAnimation(3, 100, new Duration(new TimeSpan(0, 0, 0, 1, 0))) {
                        EasingFunction = new PowerEase { EasingMode = EasingMode.EaseOut }
                    };
    
                    var s = new Storyboard();
                    Storyboard.SetTargetName(s, translationName);
                    Storyboard.SetTargetProperty(s, new PropertyPath(TranslateTransform.YProperty));
                    var storyboardName = "s" + s.GetHashCode();
                    Resources.Add(storyboardName, s);
    
                    s.Children.Add(anim);
    
                    s.Completed +=
                        (sndr, evtArgs) => {
                            panel.Children.Remove(e);
                            Resources.Remove(storyboardName);
                            UnregisterName(translationName);
                        };
                    s.Begin();
                }
            }
    
            [STAThread]
            public static void Main() {
                var app = new Application();
                app.Run(new MainWindow());
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-04 02:54

    Leave out the Storyboard:

    var T = new TranslateTransform(40, 0);
    Duration duration = new Duration(new TimeSpan(0, 0, 0, 1, 0));
    DoubleAnimation anim = new DoubleAnimation(30, duration);
    T.BeginAnimation(TranslateTransform.YProperty, anim);
    

    (small fix for syntax)

    0 讨论(0)
  • 2021-02-04 03:00

    I have a Solution using XAML / C# Combo. In your XAML file define:

    <UserControl.RenderTransform>
        <TranslateTransform x:Name="panelTrans" Y="0"></TranslateTransform>
    </UserControl.RenderTransform>
    

    This will give you the ability to do the following in the C# code:

            Storyboard.SetTargetName(mFlyInDA, "panelTrans");
            Storyboard.SetTargetProperty(mFlyInDA, new PropertyPath("Y"));
    

    The rest is business as usual. Create a DoubleAnimation, set its properties, add it as a child to your Storyboard, call the Begin function on the story board.

    0 讨论(0)
提交回复
热议问题