3

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イベントは以前に発生します。

問題は、私のカスタムコンポーネントが、コントロールテンプレートが設定された見た目のないコンポーネントであるということです。ロードされたイベントで、ビジュアルツリーを調べて、いくつかの追加のデフォルト値を適用したいのですが、テンプレートがまだ適用されていないため、ビジュアルツリーは空です。

外部から(つまり、コンポーネントを変更せずに)、ロードされたらすぐにビジュアルツリーを反復処理できるようにする方法はありますか?

4

1 に答える 1

0

TabControl内部で仮想化を行います。この SO の質問の回答に従って、これを無効にすることができます: How to preserve control state within tab items in a TabControl

于 2012-09-27T12:10:36.960 に答える