2010-05-15 21 views
13

Tôi có một khung hình WPF mà trên đó tôi tự động tạo các đối tượng từ mã. Các đối tượng này đang được chuyển đổi bằng cách thiết lập thuộc tính RenderTransform và một hoạt ảnh cần được áp dụng một trong các biến đổi đó. Hiện tại, tôi không thể nhận được các thuộc tính của bất kỳ biến đổi nào thành animate (mặc dù không có ngoại lệ nào được nâng lên và hoạt ảnh xuất hiện để chạy - sự kiện đã hoàn thành được nâng lên).WPF: Hoạt hình TranslateTransform từ mã

Ngoài ra, nếu hệ thống hoạt ảnh bị nhấn mạnh, đôi khi sự kiện Storyboard.Completed không bao giờ được nâng lên.

Tất cả các ví dụ tôi đã thực hiện trên các biến đổi từ XAML. MSDN documentation gợi ý rằng thuộc tính x: Name của một biến đổi phải được đặt để nó có thể hoạt hình, nhưng tôi chưa tìm được cách làm việc để đặt nó từ mã.

Bất kỳ ý tưởng nào?

Dưới đây là danh sách mã đầy đủ nhằm tái tạo vấn đề:

using System; 
using System.Diagnostics; 
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 { 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    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); 
       tg.Children.Add(translation); 
       tg.Children.Add(new RotateTransform(i * 30)); 
       e.RenderTransform = tg; 

       panel.Children.Add(e); 

       var s = new Storyboard(); 
       Storyboard.SetTarget(s, translation); 
       Storyboard.SetTargetProperty(s, new PropertyPath(TranslateTransform.XProperty)); 

       s.Children.Add(
        new DoubleAnimation(3, 100, new Duration(new TimeSpan(0, 0, 0, 1, 0))) { 
         EasingFunction = new PowerEase {EasingMode = EasingMode.EaseOut} 
        }); 

       s.Completed += 
        (sndr, evtArgs) => { 
         Debug.WriteLine("Animation {0} completed {1}", s.GetHashCode(), Stopwatch.GetTimestamp()); 
         panel.Children.Remove(e); 
        }; 

       Debug.WriteLine("Animation {0} started {1}", s.GetHashCode(), Stopwatch.GetTimestamp()); 

       s.Begin(); 
      } 
     } 

     [STAThread] 
     public static void Main() { 
      var app = new Application(); 
      app.Run(new MainWindow()); 
     } 
    } 
} 

Trả lời

12

Có vẻ rằng sau một chút Googling tôi giải quyết vấn đề bản thân mình. Rất cảm ơn MSDN documentationa post in MSDN forums by Antares19.

Nói tóm lại:

  • Đối với một đối tượng Freezable (như TranslateTransform) được nhắm mục tiêu bởi một Storyboard, nó phải có một tên đăng ký. Điều này có thể được thực hiện bằng cách gọi FrameworkElement.RegisterName (..).

  • Tôi đã thêm đối tượng Storyboard vào ResourceDictionary của cùng một phần tử Khung mà tôi đã đăng ký TranslateTransform. Điều này có thể được thực hiện bằng cách gọi ResourceDictionary.Add (..)

Dưới đây là các mã được cập nhật, hiện sinh động độc đáo, và thanh ghi/deregisters các nguồn lực bổ sung:

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()); 
     } 
    } 
} 
21

Bỏ 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); 

(sửa chữa nhỏ cho các cú pháp)

+0

tốt và đơn giản, bạn đã giúp tôi hết sức. –

3

tôi có một giải pháp sử dụng XAML/C# Combo. Trong file XAML của bạn xác định:

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

này sẽ cung cấp cho bạn khả năng làm như sau trong mã C#:

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

Phần còn lại là kinh doanh như bình thường. Tạo một DoubleAnimation, thiết lập các thuộc tính của nó, thêm nó như một đứa trẻ vào Storyboard của bạn, gọi hàm Begin trên bảng câu chuyện.

Các vấn đề liên quan