9

PropertyChangedCallback を持つ依存関係プロパティを持つ WPF CustomControl を作成しています。その Callback メソッドでは、GetTemplateChild() メソッドを使用して OnApplyMethod から取得したコントロールの一部に値を設定しようとしています。

問題は、PropertyChangedCallback が (一部のシステムでは) OnApplyTemplate の前に呼び出されるため、コントロール パーツがまだ null であることです。

私が現在使用している回避策は、e.NewValue を PropertyChangedCallback からメンバー変数に保存してから、OnApplyTemplate() で SetValue(dp, _savedValue) を呼び出すことです。

この問題に対処する適切な方法は何ですか、またはすでに最適なソリューションを使用していますか?

4

1 に答える 1

8

それが私たちがしていることです-pricipleの問題を解決するのではなく、それを修正するための明確な方法を提供します。

  1. DP値変更イベントのハンドラーを作成します。OnValueChanged()とします。通常、どのDPが変更されたかがわかっており、常に現在の値を取得できるため、パラメーターは必要ありません。

  2. コンストラクターを使用してDeferredActionというクラス/構造体を作成し、System.Actionを受け入れます(これはOnValueChanged()への参照になります)。このクラスには、プロパティActionとExecute()というメソッドがあります。

これが私が使用するものです:

class DeferredAction
{
   private Action action;

    public DeferredAction(Action action)
    {
        this.action = action;
    }

    private Action Action
    {
        get { return this.action; }
    }

    public void Execute()
    {
        this.Action.Invoke();
    }
}
  1. コントロールでリストを作成します。コレクションは、正常に適用できるようになるまで(通常、base.OnApplyTemplate()の後)、DeferredActionのリストを保持します。アクションが適用されたら、二重処理を回避するためにコレクションをクリアする必要があります。

  2. OnValueChanged内で、Partがnullでないかどうかを確認し(そうである可能性が高い)、nullでない場合は、前の手順で作成したリストにDeferredAction(OnValueChanged()の新しいインスタンスを追加します。OnValueChanged()は2つの目的です。ハンドラーは、DP値変更ハンドラーから直接呼び出すことができます。パーツがヌルでない場合は、実行可能な遅延アクションとして使用されます。

  3. OnApplyTemplateは、遅延アクションリストをループし(存在する場合は適用されていません)、それぞれに対してExecuteを呼び出します。最後にリストをクリアします。

乾杯

于 2011-01-21T09:21:48.337 に答える