2

DependencyProperty を値からターゲット値 (コード内) にアニメーション化しようとし、アニメーションが終了 (またはキャンセル) されたら、最終値をプロパティに設定します。最終値は、アニメーションが終了した場合は To 値、またはアニメーションがキャンセルされた場合は (アニメーションによって)現在計算された値のいずれかになります。

デフォルトでは、アニメーションにはこの動作がなく、アニメーションは完了しても実際の値を変更しません。

失敗した試み

少し前に、前述の動作を実現するためにこのヘルパー メソッドを作成しました。

static void AnimateWithAutoRemoveAnimationAndSetFinalValue(IAnimatable element,
    DependencyProperty property,
    AnimationTimeline animation)
{
    var obj = element as DependencyObject;
    if (obj == null)
        throw new ArgumentException("element must be of type DependencyObject");
    EventHandler handler = null;
    handler = (sender, e) =>
    {
        var finalValue = obj.GetValue(property);
        //remove the animation
        element.BeginAnimation(property, null);
        //reset the final value
        obj.SetValue(property, finalValue);

        animation.Completed -= handler;

    };

    animation.Completed += handler;

    element.BeginAnimation(property, animation);
}

残念ながら、誰かが BeginAnimation(property,null ) を呼び出してアニメーションが削除された場合、Completed イベントは発生しないように見えるため、アニメーションがキャンセルされたときに最終値を正しく設定できません。さらに悪いことに、イベントハンドラーも削除できません...

誰かがこれをきれいな方法で行う方法を知っていますか?

4

1 に答える 1

1

アニメーションが終了した直後に、アニメーションが開始される前に値を初期値に戻そうとしているようです。アニメーションを停止すると (またはアニメーション タイムラインが終了すると)、これは実際には自動的に行われます。WPF のアニメーションは、プロパティの現在の値の上にある値のオーバーレイと見なすことができます。アニメーションを停止または削除すると、オーバーレイが削除され、以前の値が再び表示されるようになります。元の値は失われていません。一時的に隠されています。

プロパティを明示的に以前の値に設定することは、通常、値がオブジェクトでローカルに設定されていない場合にメモリ オーバーヘッドが発生する可能性があるため、不適切な方法です。また、これは後で微妙な問題を引き起こす可能性があります。たとえば、古い値がスタイルから派生したものである場合、スタイルが変更されてもプロパティは変更されません。

それでも現在の値を抽出して後で復元する必要があると思われる場合は、GetValue() の代わりに ReadLocalValue() を使用してください。値がローカルに設定されていない場合、これは DepenencyProperty.UnsetValue を返します。その後、プロパティが最初にローカル値を持っていたかどうかに応じて、ClearValue() または SetValue() を条件付きで呼び出すことができます。

于 2009-02-27T00:22:22.177 に答える