最初将控件创建为折叠时,ContentPresenter.Loaded不会引发

时间:2011-07-19 11:48:06

标签: windows-phone-7

也许希望有一个奇迹,但让我们试试: - )

MyControl派生自Control。它的ControlTemplate包含

<ContentPresenter ContentTemplate="{TemplateBinding EditorTemplate}"/>

(省略其他细节。)

派生控件提供合适的EditorTemplate。例如,MyTextControl指定由TextBox组成的模板。 (当然,有适当的绑定。)

我不会描述什么有效(大多数情况),但不能描述:

创建了折叠的MyTextControl实例。稍后,此控件可见。以下是发生的事情:

  • 创建了MyTextControl实例,设置为Collapsed
  • MyTextControl.Loaded事件:此时可视树包含没有子项的MyTextControl。
  • 在Loaded处理程序中,我调用ApplyTemplate()。反过来,可视树被修改为MyTextControl - &gt; ContentPresenter。这就是全部,没有更多的孩子。
  • Stil in Loaded handler,我将Loaded处理程序分配给ContentPresenter。
  • 有时候控件会变得可见。其可视树由Tex​​tBox内部填充:Border - &gt; ContentControl - &gt; ContentPresenter - &gt;内部TextBoxView。换句话说,控制就可以了。

问题是没有调用ContentPresenter Loaded处理程序,即我无法确定控件准备就绪的时刻。

我尝试了另一种解决方案,即不是强制ApplyTemplate()而是在MyControl.OnApplyTemplate()中等待。顺序:

  • 创建了MyTextControl实例,设置为Collapsed
  • 在Loaded处理程序中,可视化树包含没有子项的MyTextControl。
  • 控件可见。
  • 在OnApplyTemplate()中,可视树是MyTextControl-&gt; ContentPresenter。
  • 在OnApplyTemplate()中的Stil,我将Loaded处理程序分配给ContentPresenter。
  • 其余的和以前一样。可视树由Tex​​tBox内部填充(控件工作),但上面的处理程序不会被调用。

有人知道如何确定控件满载的时刻吗?

请注意,我使用其他几个MyControl派生的控件执行了上述操作。对于它们中的每一个,上述场景之一都有效(有时是一个,有时是另一个),但基于TextBox的控件是第一个我无法识别加载时刻的控件。

另请注意,当控件始终可见时,不会发生此问题。

1 个答案:

答案 0 :(得分:1)

好的,我会自己回答。我目前在1天和几十次测试后的结论是,加载的事件是针对鸟类的。它发生在控制生命周期的各个阶段,如果是复合控制,则无法保证控制功能完全正常。在某些情况下,根本不会被解雇。

通过调用ApplyTemplate()来强制模板构建也不是解决方案,因为在某些情况下它可能会导致构建部分控制树。

OnApplyTemplate遇到类似的问题 - 当只构建部分控制树时可能会调用它。

在确认上述声明后,我决定试一下LayoutUpdated事件。我在OnApplyTemplate()中设置了处理程序(我试图使用最新的可能时刻)并调查控制树。作为第一个近似值,检查ContentPresenter是否有子项似乎就足够了。如果是这样,我们会说控件已加载并取消注册LayoutUpdated处理程序。可以使用更加软化的测试,但我刚才描述的那些微不足道的测试正在进行广泛的控制。

最初我担心LayoutUpdated解决方案效率低下,但看起来(使用描述的组织)第一个处理程序调用恰好是控件被“加载”的地方。