2010-03-28 4 views
7

저는 MVVM 앱을 작성 중이며 몇 가지 애니메이션을 넣기 시작했습니다. 스토리 보드를 시작하는 ViewModel에서 무언가를 호출하고 싶습니다. This blog had a promising approach to it,하지만 실제로 작동하지 않습니다. IDChanged 처리기는 어떤 이유로 든 절대 실행되지 않습니다.WPF/MVVM의 ViewModel에서 애니메이션 시작하기

또한 EventTriggers에서 애니메이션을 시작할 수도 있지만 ViewModel에서 애니메이션을 시작하는 방법을 알지 못합니다.

답변

0

나는 AnimationStarted 이벤트를 내 ViewModel에 어떤 애니메이션의 키 문자열과 함께 추가하게되었습니다. 그런 다음 뷰에서 프로그래밍 방식으로 애니메이션을 만들고 AnimationStarted 이벤트에 가입하고 해당 애니메이션이 실행될 때 적절한 애니메이션을 해제합니다.

1

내 VM에 응용 프로그램의 상태를 반영하는 속성이 있습니다. 뷰의 애니메이션 요소에는 VM 속성에 특정 값이있을 때 스토리 보드를 시작하는 데이터 트리거가 있습니다.

+0

내가 그렇게하는 방법을 알고있다. 조건을 입력 할 때 스토리 보드를 시작하는 트리거를 설정합니다. 하지만 일회성 애니메이션 만하면됩니다. UI 요소에 신속하고 일시적인 플래시를 적용하여 관심을 끌고 싶습니다. – RandomEngy

+0

일반화를 고려하지 않았으므로 이것이 도움이되는지 잘 모르겠습니다. 한 때 비슷한 필요성이있었습니다. 1 분 동안 아무런 활동이 없다면 버튼을 '깜박'시켜야했습니다. 나는 스토리 보드를 버튼에 붙임으로써 스토리 보드가 아무 것도하지 않을 것이고 플래시를 할 것이다. 제 경우에는 버튼을 클릭하면 사라져 시나리오가 더 단순 해졌습니다. 관심을 끌기위한 UI 요소의 플래시는 뷰와 관련된 것처럼 들립니다. 보기만으로 플래시를 실행할시기를 결정할 수있는 방법이 있습니까? VM이 UI 요소를 깜박 거리는 이유는 무엇입니까? 죄송합니다. 많은 도움이되지 않을 수 있습니다. – Carlos

+0

음, 한 창에서 실행되는 여러 명령이 다른 창에서이 플래시를 트리거합니다. 내 윈도우 모델은 VM이 창 간의 관계를 알고 있지만 뷰는 그렇지 못하도록 설정되어 있습니다. – RandomEngy

5

DataTrigger를 사용하여이를 내 ViewModel의 속성에 바인딩했습니다. "FlashingBackGround"속성이 "ON"으로 설정되면 스토리 보드 애니메이션이 시작됩니다. 또한

프로젝트에 대한 참조를 "Microsoft.Expression.Interactions"

XAML 포함해야합니다 (이 루트 노드에서 직접 이동)

<Window 
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
    xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 
    x:Name="window" > 

    ... 

    <i:Interaction.Triggers> 
     <ei:DataTrigger Binding="{Binding FlashingBackground, Mode=OneWay}" Value="ON"> 
     <ei:ControlStoryboardAction Storyboard="{StaticResource MyAnimation}"  
               ControlStoryboardOption="Play"/> 
     </ei:DataTrigger> 
    </i:Interaction.Triggers> 

    ... 
</Window> 

뷰 모델 :

private void TurnOnFlashingBackround() 
    { 
     FlashingBackground = "ON"; 
    } 

    private string _FlashingBackround = "OFF"; 

    public string FlashingBackground 
    { 
     get { return _FlashingBackround; } 

     private set 
     { 
      if (FlashingBackground == value) 
      { 
       return; 
      } 

      _FlashingBackround = value; 
      this.OnPropertyChanged("FlashingBackground"); 
     } 
    } 

    public new event PropertyChangedEventHandler PropertyChanged; 

    private void OnPropertyChanged(string propertyName) 
    { 
     if (this.PropertyChanged != null) 
     { 
      this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

마지막으로 ViewModel은 "INotifyPropertyChanged"에서 상속해야합니다.

+6

흥미로운 접근 방법. 하지만 "ON"/ "OFF"문자열 대신 '부울'만 사용하는 것이 어떻습니까? –

+0

"System.Windows.Interactivity.dll"도 추가해야합니다. –

0

같은 문제가 발생했는데 애니메이션이 코드에 포함되어있어 그 중 일부는 실제로 도움이되지 않았습니다. 그 중 일부는 크고 복잡하며 가변적 인 변수가 필요했기 때문에 코드에 머물러 있어야했습니다. 애니메이션을 트리거하는 사용자 정의 컨트롤 (뷰)에 종속성 속성을 추가하고이를 뷰 모델의 속성에 바인딩하여 해결했습니다. 이것이 잘 작동하기 때문에 이것이 무엇인가를 위반하는지 알지 못한다. 환호, stepp

발췌 : 뒤에

(보기)에서 UserControl 코드 :

public override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate(); 
     SetAnimationBindings(); 
    } 

    private void SetAnimationBindings() 
    { 
     _dialogStartPosition = mbFolderBrowse.Margin; 

     var propName = "StartDialogAnimation"; 
     var binding = new Binding(propName) { Mode = BindingMode.TwoWay }; 
     this.SetBinding(DialogAnimationProperty, binding); 

     propName = "StartProgressAnimation"; 
     binding = new Binding(propName) { Mode = BindingMode.TwoWay }; 
     this.SetBinding(ProgressAnimationProperty, binding); 
    } 

    #region Animation Properties 
    #region DialogAnimation 
    public static readonly DependencyProperty DialogAnimationProperty = 
     DependencyProperty.Register("DialogAnimation", typeof(bool), 
      typeof(Manage), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnDialogAnimationChanged)); 
    public bool DialogAnimation 
    { 

     get { return (bool)this.GetValue(DialogAnimationProperty); } 
     set 
     { 
      var oldValue = (bool)this.GetValue(DialogAnimationProperty); 
      if (oldValue != value) this.SetValue(DialogAnimationProperty, value); 
     } 
    } 

    private static void OnDialogAnimationChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) 
    { 
     Manage m = o as Manage; 

     if ((bool)e.NewValue == true) 
      m.SlideInDialogPanel(); // animations 
     else 
      m.SlideOutDialogPanel(); 
    } 
    #endregion 

보기 - 모델 :

public bool StartDialogAnimation 
{ 
    get { return _startDialogAnimation; } 
    set 
    { 
     if (_startDialogAnimation != value) 
     { 
      _startDialogAnimation = value; 
      RaisePropertyChanged("StartDialogAnimation"); 
     } 
    } 
}