2011-10-19 2 views
5

여기에 일종의 MVVM 위반 점이있는 것 같습니다.MVVM을 사용하여 이벤트에서 애니메이션 재생

기본 뷰 모델 객체의 "상태"속성이 변경된 경우 컨트롤에 0.5 초 (1.0에서 DoubleAnimation까지)의 불투명도 애니메이션을 적용하고 싶습니다. DataTrigger를 사용하여 처음에이 작업을 수행했지만 변경 사항, 즉 주어진 값에 반응하는 방법을 찾지 못했기 때문에 VM 객체의 "Status"속성을 특수 "보류 중"값으로 설정해야합니다 의도 한 값으로

  1. : (? BTW 어떤 변화에 반응 할 수있는 방법이 있나요)

    내가 지금까지 시도한 것입니다 ... 그래서 내가 대신 Eventtriggers에 바이올린을 켜는 시작 해키했다 보통 사용하기 EventTrigger

이것은 RoutedEvent를 필요로하는 것처럼 보이지만 내 기본보기 모델 객체가 DependencyObject에서 상속되어야한다는 것을 나타냅니다. i:Interaction.Triggers

내가 듣고 정상 .NET 이벤트에 반응하지만 그 접근 방식을 사용하여 StoryBoard을 시작하는 방법을 발견하지 않았습니다 수있는 그런 방법을 사용

  1. . i:Interaction.Triggers를 사용하고 Behavior

이 실험을 작성

  1. 내가 관련 컨트롤에 내 사용자 지정 동작을 첨부 할 수있는 방법을 찾을 수 없습니다 사실에 부족했다.

    는 XAML 어떻게 생겼는지입니다 :

    <cc:MyControl> 
         <i:Interaction.Triggers> 
          <i:EventTrigger EventName="Updated"> 
           <i:Interaction.Behaviors> 
            <cv:OpacityBehavior Duration="0:0:0:5" /> 
           </i:Interaction.Behaviors> 
          </i:EventTrigger> 
         </i:Interaction.Triggers> 
    

    그리고 여기에 사용자 지정 동작의 다음 XAML 파서가 필요하기 때문에 작동하지 않았다

    class OpacityBehavior : Behavior<MyControl> 
    { 
        public Duration Duration { get; set; } 
    
        protected override void OnAttached() 
        { 
         base.OnAttached(); 
         var animation = new DoubleAnimation(0.5, 1, Duration, FillBehavior.HoldEnd); 
         var associatedObject = lookupVisualParent(this); 
         associatedObject.BeginAnimation(UIElement.OpacityProperty, animation); 
        } 
    } 
    

    는 MyControl "에 직접 부착 할 "하지만 이벤트 트리거에 첨부해야합니다.

    class OpacityBehavior : Behavior<DependencyObject> 
    { 
        public Duration Duration { get; set; } 
    
        protected override void OnAttached() 
        { 
         base.OnAttached(); 
         var animation = new DoubleAnimation(0.5, 1, Duration, FillBehavior.HoldEnd); 
         var associatedObject = lookupVisualParent(this); 
         associatedObject.BeginAnimation(UIElement.OpacityProperty, animation); 
        } 
    
        private UIElement lookupVisualParent(DependencyObject dObj) 
        { 
         if (dObj is UIElement) 
          return (UIElement) dObj; 
    
         if (dObj == null) 
          return null; 
    
         return lookupVisualParent(LogicalTreeHelper.GetParent(dObj)); 
        } 
    } 
    

    lookupVisualParent이 작동하지 않는다는 사실에 실패 : 그럼이 방법을 시도했다. 동작의 논리 상위는 항상 null입니다.

    이것은 상당히 일반적인 작업이어야한다는 인상을 받습니까? 이 문제에 대한 좋은 해결책이 있습니까? 이벤트가 발생했을 때 애니메이션을 시작하기 위해 DependencyObject에서 파생되도록 뷰 모델 클래스를 작성하는 것이 이상하다는 것을 알게되었습니다.

    건배

답변

4

당신은 단순히 플래그를 사용할 수 있습니다 : 당신의 VM은 'RecentlyChangedFlag을'라고 불리는 플래그를 설정합니다. 적절한 값이 변경 될 때마다 true, 그 다음에 false으로 펄스하십시오. 다음과 같이 할 수 있습니다.

위 코드를 ChangedFlag = true으로 설정하면 애니메이션이 시작될 것을 알릴 수 있습니다. WPF가 true 값을 쿼리 한 후 false로 다시 설정됩니다.

그런 다음 RecentlyChangedFlag 값이 true 일 때 애니메이션이 발생하게하려면, 예를 들어 EnterAction입니다.

희망이 있습니다.

+0

고마워요.하지만 그건 원래 어떻게 "해결"했나요 (DataTrigger 사용), 제가 OP에서 지적했듯이, 그것은 해킹입니다. 나는 이것이 WPF에 상당히 익숙하기 때문에 이것이 실제로 VM의 동작/애니메이션을 트리거하는 일반적인 방법 일지 모르지만 나에게는 이것이 없어야하는 한계를 해결하는 것처럼 보입니다. VM의 이벤트에서 애니메이션을 트리거 할 수 없습니까? –

+0

뷰를 사용할 수있는 모델로 모델을 변환하는 ViewModel이 있습니다. 이와 같이 이런 일을 할 수있는 완벽한 장소입니다. hacky IMO와 중요한 것이 변경된 것을 나타내는 플래그가 VM에 존재해야합니다. ViewModel이 독자적으로 일어나는 한 문제는 아닙니다. 말하는 이벤트가 무엇이든 나타내는 플래그가있는 ViewModel - 제대로 호출하면 너무 어색해 보이지 않습니까? –

+1

나는 이것에 대해 종교적이지는 않겠지 만, 사건에서 애니메이션을 트리거하는 것은 불가능하다는 것이 이상하게 보입니다. 결국, 이벤트는 상태 변화를 알리는 신호입니다. 첫 번째 속성에 상태 변경을 알리기 위해 두 번째 속성을 추가해야하는 경우 IMHO를 해결할 수 있습니다. WPF에서 사용할 수있는 도구가 부족하다는 사실에 놀랐습니다. 나는이 특별한 경우에 "국가 재산 솔루션"으로 확실히 살 수 있지만 내 VM 클래스는 미래에 그러한 자산으로 가득 차있을 것이라고 생각합니다. 더 좋은 방법이 있어야합니다, 그렇죠? –

관련 문제