[私の他の質問からの回答をここにコピーします。]
すごいソーセージ!私はそれを考え出した!
通常、Initialized
イベントを受け取る (またはオーバーライド内にいるOnInitialized
) 場合、XAML 設定のプロパティ値にアクセスできます。ただし、UI をハイドレートし、関連するメンバー変数を設定するために呼び出されるUserControl
ことに依存するため、クラスの動作は少し異なります。InitializeComponent
問題は、呼び出しがコンストラクター内にあることです。これにより、呼び出しが終了しOnInitialized
(したがってInitialized
イベントが発生します)、XAML セットのプロパティが適用される前に発生します。つまり、まだそれらにアクセスできないことを意味します。必要です。
Loaded
これらのプロパティに基づいて初期化を完了するために、イベントの良い使い方だと思うかもしれませんが、そこで追加の初期化を実行している場合、消費者がLoaded
イベントにサブスクライブする場合に、消費者との潜在的な競合状態を作成しています。あなたの前にそれを取得し、ハンドラーであなたのコントロールにアクセスしようとすると、初期化されていないコントロールにアクセスします。
その後、何かが起こりました...上で示したようにInitializeComponent
、コンストラクターから呼び出しを削除すると、Initialized
イベントは期待どおりに機能しますが、まだ呼び出していないため、もちろん UI はまだハイドレートされていませんInitializeComponent
。
OnInitialized
では、その呼び出しをオーバーライドの先頭、つまり への呼び出しのbase.OnInitialized
前、つまりInitialized
イベントが発生する前に移動するとどうなるでしょうか?
うん!それはうまくいきました!:)
Initialized
この方法では、XAML で設定されたプロパティを取得できるだけでなく、(イベントは言うまでもなく)誰かがイベントを取得する前に UI を完全に読み込むこともできますLoaded
。これが、イベントのInitialized
使用方法です。
以下は修正されたコードです...
public partial class TestControl : UserControl
{
protected override void OnInitialized(EventArgs e)
{
InitializeComponent();
base.OnInitialized(e);
}
public static readonly DependencyProperty TestValueProperty = DependencyProperty.Register(
"TestValue",
typeof(string),
typeof(TestControl),
new UIPropertyMetadata("Original Value"));
public string TestValue
{
get { return (string)GetValue(TestValueProperty); }
set { SetValue(TestValueProperty, value); }
}
}
- 注: そこで他のことを行う必要がある場合を除き、コンストラクターはもう必要ありません。その場合は、呼び出しの後まで名前で構成要素のコントロールにアクセスできないことを覚えておいてください
InitializeComponent
。ただし、これは、そのような名前ベースの初期化をInitializeComponent
との間で移動することを計画する必要があることを意味し、問題なくbase.OnInitialize
動作します。