Windows phone 7 当控件最初创建为折叠时,不会引发ContentPresenter.Loaded

Windows phone 7 当控件最初创建为折叠时,不会引发ContentPresenter.Loaded,windows-phone-7,Windows Phone 7,也许希望出现奇迹,但让我们试试:-) MyControl源于控件。其控制模板包含 <ContentPresenter ContentTemplate="{TemplateBinding EditorTemplate}"/> (其他细节省略。) 派生控件提供合适的编辑器模板。例如,MyTextControl指定由文本框组成的模板。(当然,要有合适的绑定。) 我不会描述什么是有效的(大多数场景),但什么是无效的: 将创建一个折叠的MyTextControl实例。稍后,此控件将变为可

也许希望出现奇迹,但让我们试试:-)

MyControl源于控件。其控制模板包含

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

(其他细节省略。)

派生控件提供合适的编辑器模板。例如,MyTextControl指定由文本框组成的模板。(当然,要有合适的绑定。)

我不会描述什么是有效的(大多数场景),但什么是无效的:

将创建一个折叠的MyTextControl实例。稍后,此控件将变为可见。发生的情况如下:

  • 已创建MyTextControl实例,设置为已折叠
  • 加载的事件:此时可视化树包含没有子级的MyTextControl
  • 在加载的处理程序中,我调用ApplyTemplate()。反过来,可视树被修改为MyTextControl->ContentPresenter。仅此而已,没有孩子了
  • 在加载的处理程序中,我将加载的处理程序分配给ContentPresenter
  • 有时,稍后控件将变为可见。它的可视化树由TextBox内部构件填充:Border->ContentControl->ContentPresenter->InternalTextBoxView。换言之,控件只起作用
问题在于未调用ContentPresenter加载的处理程序,即我无法确定控件准备就绪的时刻

我尝试了另一种解决方案,也就是说,我没有强制使用ApplyTemplate(),而是在MyControl.OnApplyTemplate()中等待。顺序如下:

  • 已创建MyTextControl实例,设置为已折叠
  • 在加载的处理程序中,可视化树包含没有子级的MyTextControl
  • 控件是可见的
  • 在OnApplyTemplate()中,可视树是MyTextControl->ContentPresenter
  • 仍然在OnApplyTemplate()中,我将加载的处理程序分配给ContentPresenter
  • 其余的和以前一样。可视化树由TextBox内部构件填充(控件工作),但上面的处理程序没有被调用
有人知道如何识别控件满载的时刻吗

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


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

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

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

OnApplyTemplate也有类似的问题——当只构建部分控制树时可能会调用它

在确认了上述声明后,我决定尝试安排一次更新的活动。我在OnApplyTemplate()中设置了处理程序(我尝试使用最新的可能时刻),并研究了控制树。作为第一个近似值,检查ContentPresenter是否有子项似乎就足够了。如果是这样,我们将说该控件已加载并注销LayoutUpdated处理程序。可以使用一个更具仿真性的测试,但我刚才描述的那个小测试适用于广泛的控件


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

在最后的代码中,我还必须考虑SizeChanged事件,因为LayoutUpdated事件可能会延迟。