2010-05-15 9 views
13

코드에서 동적으로 개체를 만드는 WPF 캔버스가 있습니다. 이러한 객체는 RenderTransform 속성을 설정하여 변형되며 애니메이션은 이러한 변형 중 하나에 적용되어야합니다. 현재 예외가 발생하지 않고 애니메이션이 실행되는 것으로 나타 났지만 완료된 이벤트가 발생하더라도 모든 애니메이션 변형 속성을 가져올 수 없습니다.WPF : 코드에서 TranslateTransform에 애니메이션 적용

또한 애니메이션 시스템에 부하가 걸리면 Storyboard.Completed 이벤트가 발생하지 않는 경우가 있습니다.

나는 모든 예제에서 XAML의 변형을 애니메이션화했습니다. MSDN documentation은 변환의 x : Name 속성이 애니메이션 가능하도록 설정되어야한다고 제안하지만 코드에서 설정하는 작업 방법을 찾지 못했습니다.

아이디어가 있으십니까?

가 여기에 문제가 재생 전체 코드 목록입니다 :

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

답변

12

이 보인다 인터넷 검색의 비트가 나는 문제를 스스로 해결 한 후. MSDN documentationa post in MSDN forums by Antares19 덕분입니다. 요약

: 스토리 보드에 의해 타겟팅 될 (TranslateTransform 같이)은 Freezable 객체의 경우

  • , 그것은 등록 된 이름이 있어야합니다. 이 작업은 FrameworkElement.RegisterName (..)을 호출하여 수행 할 수 있습니다.

  • TranslateTransform을 등록한 동일한 Framework 요소의 ResourceDictionary에 Storyboard 개체를 추가했습니다. 이것은

    다음

지금 잘 애니메이션 업데이트 된 코드, 그리고 등록/등록 해제 추가 자원 ResourceDictionary.Add (..)를 호출하여 수행 할 수 있습니다

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

스토리 보드를 남겨주세요 :

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

(구문 작은 FIX)

+0

좋은 단순한 당신은 나에게 도움을 주었다. –

3
는 XAML

I/C# 콤보를 사용하는 용액이있다. 당신의 XAML 파일에서 정의

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

이 당신에게 C# 코드에서 다음을 수행 할 수있는 기능을 제공합니다 :

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

나머지는 평소와 같이 사업이다. DoubleAnimation을 만들고, 속성을 설정하고, 스토리 보드에 어린이로 추가하고, 스토리 보드에서 Begin 함수를 호출합니다.

관련 문제