2011-10-19 17 views
5

ここで何らかのMVVMのブレークポイントに達したようです。MVVMを使用してイベントからアニメーションをトリガーする

基本的なビューモデルオブジェクトの "Status"プロパティが変更されたときに、不透明度を半分(DoubleAnimationが0.5から1.0に)アニメーション化されるようにしたいと思います。私はDataTriggerを使用してこれを最初に達成しましたが、何らかの変化に反応する方法が見つからなかったので、VMオブジェクトの "Status"プロパティを特別な "保留中"の値に置き換えてから設定しなければなりませんその意図された値にする。 (ところでANY変化に反応する方法はありますか?)

これはハックだったので、私はこれは私がこれまで試したものです...代わりにEventTriggersで

をいじる開始しました:

  1. EventTrigger

これはRoutedEventを必要とするように思われますが、そのためには、基になるビューモデルオブジェクトがDependencyObjectから継承する必要があります。 i:Interaction.Triggers

私が聞くと、通常の.NETイベントに反応するが、私はそのアプローチを使用してStoryBoardを開始する方法を発見していないことができますこの方法を使用して

    1. i:Interaction.Triggersを使用してBehavior

    を書くこの実験では、私はそれに関連するコントロールに私のカスタム動作を添付する方法を発見していないという事実に及びませんでした。

    この

    は、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にパルスします。あなたはこれを次のようにすることができます:

Ie.上記のコードをChangedFlag = trueに設定して、アニメーションの開始を通知する必要があります。 WPFが真の値を照会した後、falseにリセットされます。

RecentlyChangedFlagの値がtrueの場合は、たとえばEnterActionのようにアニメーションが発生します。

希望に役立ちます。

+0

ありがとうございましたが、それはもともと(DataTriggerを使用して)私が "解決"した方法ですが、私がOPで指摘したように、それはハッキーです。私はかなりWPFの新機能ですので、これは実際にはVMからのビヘイビアー/アニメーションをトリガーする通常の方法ですが、これはそこにあるべきではない制限を回避するように見えます。 VM内のイベントからアニメーションをトリガすることはできません。 –

+0

ViewModelは、モデルをビューが使用できるものに変換するために存在します。このようなことをするのに最適な場所です。ハッキーなIMOや、重要な変更がVMに存在するはずであることを示すフラグではありません。 ViewModelが単独で立ち上がる限り、それは問題ではありません。あなたが話している「イベント」を示すフラグを持ったViewModel - あなたが正しいことを言えば、それはあまりにも外れていないようですね? –

+1

私はこれについて宗教になるつもりはありませんが、イベントからアニメーションを引き起こすことは不可能であることは奇妙に思えます。結局のところ、イベントは状態の変化を知らせるためのものです。状態の変化を最初のものに伝えるだけの第2のプロパティを追加することは、回避策IMHOです。私は、WPFで利用できるツールが不足していることに驚いています。この特定のケースでは、私は確かに "国家財産ソリューション"と一緒に暮らすことができますが、将来私のVMクラスはそのようなプロパティでいっぱいになると考えています。より良い方法がなければなりません、そうですか? –

関連する問題