我的印象是,听Loaded event将确保我可以在那时访问可视树。这似乎在大多数情况下都能正常工作,而视觉树就是我所期望的。但是,当使用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
,它位于第二个选项卡上,OnApplyTemplate
仅在切换到其选项卡时执行,但实际上是在之前引发了加载的事件。
现在的问题是我的自定义组件是一个具有控件模板集的无外观组件。在加载的事件中,我现在想要浏览可视化树并应用一些其他默认值,但由于模板尚未应用,因此可视化树为空。
是否有某种方式,从外部(即没有修改组件),以确保我可以在加载后立即遍历可视树?
答案 0 :(得分:0)
TabControl
进行了一些虚拟化。
您可以根据此SO问题中的答案禁用此功能:
How to preserve control state within tab items in a TabControl