7

ここで、ある種の MVVM 限界点に達したようです。

基になるビュー モデル オブジェクトの "Status" プロパティが変更されたときに、コントロールの不透明度を 0.5 秒間 (DoubleAnimation を 0.5 から 1.0 に) アニメーション化したいと考えています。最初は DataTrigger を使用してこれを達成しましたが、特定の値だけに対応する方法が見つからなかったため、設定する前に VM オブジェクトの「ステータス」プロパティを特別な「保留中」の値に常に切り替える必要がありました。意図した値に。(なんらかの変更に対応する方法はありますか?)

これはハッキーだったので、代わりに EventTriggers をいじり始めました...

これは私がこれまでに試したことです:

  1. 通常の使用EventTrigger

これには RoutedEvent が必要なように見えますが、それには、基になるビュー モデル オブジェクトが DependencyObject から継承する必要があります。

  1. 使用するi:Interaction.Triggers

StoryBoardそうすれば、通常の .NET イベントをリッスンして反応することができますが、そのアプローチの使用を開始する方法が見つかりません。

  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>

カスタム動作は次のとおりです。

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

XAML パーサーでは "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

1 に答える 1

4

フラグを使用するだけで済みます。VMに「RecentlyChangedFlag」というフラグを設定します。適切な値が変更されるたびにtrue、それをパルスします。falseあなたはこのようにそれをすることができます:

private bool _changedFlag;
public bool ChangedFlag
{
    get
    {
        if (_changedFlag)
        {
            _changedFlag = false;
            OnPropertyChanged("ChangedFlag");
            return true;
        }
        // (else...)
        return false;
    }
    protected set
    {
        _changedFlag = value;
        OnPropertyChanged("ChangedFlag");
    }
}

つまり、アニメーションの開始を通知するときに上記のコードを設定ChangedFlag = trueします。WPFがtrue値を照会すると、falseにリセットされます。

次に、たとえば、の値RecentlyChangedFlagがであるときにアニメーションを発生させます。trueEnterAction

お役に立てば幸いです。

于 2011-10-19T17:01:58.197 に答える