Loadedイベントを聞くと、その時点でビジュアルツリーにアクセスできるようになるという印象を受けました。これはほとんどの状況でうまく機能しているようで、ビジュアルツリーは私が期待しているものです。ただし、TabControlを使用する場合、非表示のタブのコントロールは、ロードされたイベントが発生する前にビジュアルツリーを構築しません。
この簡単な例を見てください。
<Window ...>
<Grid>
<TabControl>
<TabItem Header="Tab 1">
<my:MyTextBox />
</TabItem>
<TabItem Header="Tab 2">
<my:MyTextBox />
</TabItem>
</TabControl>
</Grid>
</Window>
MyTextBox
はカスタムコンポーネントであり、特定のイベントが発生したときにログアウトするだけです。
public class MyTextBox : TextBox
{
public MyTextBox()
{
Loaded += (s,e) => {
Console.WriteLine("MyTextBox {0}: Loaded", s.GetHashCode());
Dispatcher.BeginInvoke(()=>Console.WriteLine("MyTextBox {0}: Loaded BeginInvoke", s.GetHashCode()));
};
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
Console.WriteLine("MyTextBox {0}: OnApplyTemplate", this.GetHashCode());
}
}
そしてこれは出力です:
MyTextBox A: OnApplyTemplate
MyTextBox A: Loaded
MyTextBox B: Loaded
MyTextBox A: Loaded BeginInvoke
MyTextBox B: Loaded BeginInvoke
(changing tab to 2)
MyTextBox B: OnApplyTemplate
MyTextBox B: Loaded
MyTextBox B: Loaded BeginInvoke
ご覧のとおりB
、2番目のタブにあるforは、OnApplyTemplate
そのタブに切り替えたときにのみ実行されますが、実際には、loadedイベントは以前に発生します。
問題は、私のカスタムコンポーネントが、コントロールテンプレートが設定された見た目のないコンポーネントであるということです。ロードされたイベントで、ビジュアルツリーを調べて、いくつかの追加のデフォルト値を適用したいのですが、テンプレートがまだ適用されていないため、ビジュアルツリーは空です。
外部から(つまり、コンポーネントを変更せずに)、ロードされたらすぐにビジュアルツリーを反復処理できるようにする方法はありますか?