0

WPF アプリケーションを起動したときに、コントロールの初期化プロセス内で実際に何が起こっているのか知りたいですか?

DP はいつ初期化されますか? バインディング時?DataContext はいつ設定されますか? コントロールのコンストラクターで DataContext を使用できますか? 何か順番はありますか?

コントロールのコンストラクター内の DP のゲッター/セッターに値を設定すると、DP 値が更新されますが、すぐに値が null のデフォルト値にロールバックされるというトラップに遭遇しました。

したがって、コンストラクターが最初に初期化され、次に依存関係プロパティが初期化されると思います。

誰かがこれで私を助けることができますか?

編集:レイチェルのためだけに。dp は値 234 を受け取り、すぐに null にロールバックします。コンストラクターが最初に呼び出され、その後 dps の初期化が行われ、null がデフォルト値であるため dp が null に戻されるためだと思います。私はこれについて間違って考えていますか?コントロールまたは依存オブジェクトの初期化手順の順序は何ですか。

class MySuperDuperCoolClass : ContentControl
{
  public MySuperDuperCoolClass()
  {
    InitalizeComponents();
    this.MySuperDuperProperty = "234";
  }

  public string MySuperDuperProperty
  {
    get { return (string)GetValue(MySuperDuperPropertyProperty);}
    set { SetValue(MySuperDuperPropertyProperty, value);}
  }

  public static DependencyProperty MySuperDuperPropertyProperty =
    DependencyProperty.Register("MySuperDuperProperty", typeof(string), typeof(MySuperDuperCoolClass), 
    new PropertyMetadata(null));

}
4

2 に答える 2

1

DispatcherPriority Enumは、イベントの正確な順序を思い出すのに役立ちます。

  • 送信
  • 通常- コンストラクターはここで実行されます
  • データバインド
  • 与える
  • ロード済み
  • バックグラウンド
  • コンテキストアイドル
  • アプリケーションアイドル
  • システムアイドル
  • 非活性
  • 無効
  • 入力

ご覧のとおり、最初にコンストラクターが実行され、続いてデータ バインディングが実行されます。

DependencyProperties他のプロパティと同様に、オブジェクトが作成されたときに初期化されるため、コンストラクターが実行される前に初期化され、コンストラクターにプロパティが存在します。

DataContextプロパティまたはその他の設定は、設定しているDependencyProperties他のプロパティと同じように機能します。それらをバインディングで設定すると、コンストラクターの後に評価されます。XAML で設定すると、コンストラクターで設定されます。Loaded イベントでそれらを設定すると、すべてが構築、バインド、およびレンダリングされた後に設定されます。

このSOの回答も役立つかもしれません:

Window が作成されて表示されるときのイベントのシーケンス

要求に応じて、ウィンドウが作成されて表示されるときの WPF の主要なイベントのシーケンスを次に示します。

  1. コンストラクターとゲッター/セッターは、オブジェクトが作成されるときに呼び出されます。これには、更新されるオブジェクトとそれらを継承するオブジェクトの PropertyChangedCallback、ValidationCallback などが含まれます。

  2. 各要素がビジュアル ツリーまたは論理ツリーに追加されると、その Intialized イベントが発生します。これにより、定義できる要素固有の初期化に加えて、スタイルとトリガーが適用されていることがわかります [注: 論理ツリーのリーフに対して発生しない初期化イベントルートに PresentationSource (例: Window) がない場合]

  3. ウィンドウとその上のすべての折りたたまれていないビジュアルは測定され、各コントロールで ApplyTemplate が発生し、コンストラクターとゲッター/セッターを含む追加のオブジェクト ツリーの構築が発生します。

  4. ウィンドウとその上のすべての折りたたまれていないビジュアルは配置されています

  5. ウィンドウとその子孫 (論理とビジュアルの両方) が Loaded イベントを受け取る

  6. 最初に設定されたときに失敗したデータ バインディングはすべて再試行されます

  7. ウィンドウとその子孫には、コンテンツを視覚的にレンダリングする機会が与えられます

手順 1 ~ 2 は、ウィンドウが表示されているかどうかに関係なく、ウィンドウの作成時に実行されます。他の手順は通常、ウィンドウが表示されるまで実行されませんが、手動でトリガーすると、より早く実行できます。

質問に追加されたコードに基づいて編集

あなたのDependencyProperty.Register方法は私には面白く見えます。メソッドのシグネチャはそのメソッドのオーバーロードのいずれとも一致せず、通常のPropertyMetadataの代わりにカスタムUIPropertyクラスのように見えるものを使用してデフォルト値を設定しています。

コードが通常の署名で期待どおりに実行される場合DependencyProperty.Register、問題の原因として考えられるのは、カスタム コード内のどこか、またはプロパティの使用/設定方法にあることを確認できます。

簡単なサンプル テストに使用したコードは次のとおりです。

public partial class UserControl1 : ContentControl
{
    public UserControl1()
    {
        InitializeComponent();
        this.TestDependencyProperty = "234";
    }

    public string TestDependencyProperty
    {
        get { return (string)GetValue(TestDependencyPropertyProperty); }
        set { SetValue(TestDependencyPropertyProperty, value); }
    }

    public static DependencyProperty TestDependencyPropertyProperty =
        DependencyProperty.Register("TestDependencyProperty", typeof(string), typeof(UserControl1), 
        new PropertyMetadata(null));
}

そしてXAMLは

<ContentControl x:Class="WpfApplication1.UserControl1"
                x:Name="TestPanel" ...>
    <Label Content="{Binding ElementName=TestPanel, Path=TestDependencyProperty}"/>
</ContentControl>
于 2013-04-25T14:32:32.727 に答える
0

WPF では、コンストラクター経由ではなく PropertyMetaData を使用して DP のデフォルト値を設定しています。

public partial class UserControl1 : ContentControl
{
    public UserControl1()
    {
        InitializeComponent();
    }

    public string TestDependencyProperty
    {
        get { return (string)GetValue(TestDependencyPropertyProperty); }
        set { SetValue(TestDependencyPropertyProperty, value); }
    }

    public static DependencyProperty TestDependencyPropertyProperty =
        DependencyProperty.Register("TestDependencyProperty", typeof(string), typeof(UserControl1), 
        new PropertyMetadata("234"));
}
于 2015-10-17T09:45:20.400 に答える