2009-07-13 5 views
6

これは頻繁に発生する状況です。バインドされた値が変更されたときにアニメーションを開始する最善の方法は何ですか?

ビューでは、ViewModelプロパティ(INotifyPropertyChangedを基にしたもの)にバインドされたコントロールがあります。例:

<TextBlock Text="{Binding Path=Subtotal}"/> 

プロパティが変更されると、クリエイティブなアニメーションでユーザーに注意を促す必要があります。ビューがすでに通知に接続されており、余分なコードを大量に作成しないようにする(または少なくとも1回作成して再利用する)ということをどのように利用できるのか。データトリガーがおそらく最良の選択ですが、私はどのような値の変化に対していくつかの特定の値に対して発火させる方法を知らない。

次のオプションが頭に浮かぶ:

  • コードビハインドビューに加入し、ViewModelにで追加イベントを発生させます。
  • 値が変更されている場合はtrueを返すコンバーターを使用して、前述のプロパティにバインドされたdatatriggerを作成します。
  • 変更を「通知」するために使用されるViewModelの新しいブール値プロパティにバインドされたdatatriggerを作成します。
  • コントロールに関連付けられたビヘイビアを作成して、コントロールの依存関係プロパティの変更をサブスクライブし、アニメーションを開始します。

どちらが好きですか/使用しますか?私はオプションを忘れましたか?

P.S.解が最初にアニメーションを開始し、終了時に値の変化を反映する可能性がある場合は、いいです(しかし重要ではありません)。

答えて

3

これは私が実験した後に来たものです。

私は、依存プロパティを持つExpression Blend 3トリガを作成しました(これをサブスクリプションという)。

ここ
public class DataTriggerPlus : TriggerBase<DependencyObject> 
{ 
    public static readonly DependencyProperty SubscriptionProperty = 
     DependencyProperty.Register("Subscription", 
      typeof(string), 
      typeof(DataTriggerPlus), 
      new FrameworkPropertyMetadata("", 
       new PropertyChangedCallback(OnSubscriptionChanged))); 

    public string Subscription 
    { 
     get { return (string)GetValue(SubscriptionProperty); } 
     set { SetValue(SubscriptionProperty, value); } 
    } 

    private static void OnSubscriptionChanged(DependencyObject d, 
     DependencyPropertyChangedEventArgs e) 
    { 
     ((DataTriggerPlus)d).InvokeActions(null); 
    } 
} 

は、それがストーリーボードに接続されている方法は次のとおりです。私は私のTextBlockがにバインドされている同じ値に契約を結合して、このトリガーは、Expression Blendのここ3

からControlStoryboardActionに取り付けられており、トリガーです:

<TextBlock x:Name="textBlock" Text="{Binding TestProp}" Background="White"> 
    <i:Interaction.Triggers> 
     <local:DataTriggerPlus Subscription="{Binding TestProp}"> 
      <im:ControlStoryboardAction 
       Storyboard="{StaticResource Storyboard1}"/> 
     </local:DataTriggerPlus> 
    </i:Interaction.Triggers> 
</TextBlock> 

私はこのアプローチが大好きです。

編集:ブレンドと答えるドリューのコメント...

はい、それは付属しています。 Microsoft.Expression.Interactions.dllとSystem.Windows.Interactivityをプロジェクトに含めることができます。

はい、それは冗長です(私は、誰かがスタイルin this questionを介して行動を適用する良い方法を見つけたかどうか尋ねました)が、柔軟性の利点もあります。たとえば、ストーリーボードを開始するだけでなく、同じトリガーから状態を切り替えるなどの操作を行うこともできます。

+1

' 'はどこから来たのですか?私はそれがBlendと一緒に出荷されると思っています。ノンブレッドユーザーが利用できるのですか?私は同じことを自分のコードで達成したいと思いますが、これを必要とする多くのインスタンスがあるので、あまり冗長ではないソリューションが存在することを願っています。たぶんそれはスタイルを介して可能です... –

2

アニメーションを開始するトリガーを作成できます。このような

何か:アニメーションが完了した後に値を設定する問題の問題については

<Style> 
    <Style.Triggers> 
     <Trigger 
      Property="ViewModelProperty" 
      Value="True"> 
      <Trigger.EnterActions> 
       <BeginStoryboard Storyboard="YourStoryBoard" /> 
      </Trigger.EnterActions> 
     </Trigger> 
    </Style.Triggers> 
</Style> 

、これは痛みのビットです。ストーリーボードで完成したイベントを使用する必要があることがわかっている限り、MVVMで回避したいコードビハインドが必要です。

完了したイベントにバインドするためにEventTriggersを使用しようとしましたが、それもいくつかの複雑さをもたらします。詳細については、hereを参照してください。

+0

また、プロパティがブール値か選択肢のセットではなく、任意の文字列または数値ですか? –

+0

次に、ValueConverterを使用します。 valueConverterと同じソリューション。 –

+0

個々のバインディングごとに値コンバーターを作成しない限り、値コンバーターは値が変更されたことをどのように知っていますか? –

関連する問題