WPF概念解析一: FrameworkElement的Loaded事件和Initialized事件
WPF FrameworkElement的Loaded事件和Initialized事件
在WPF中FrameworkElement类定义了两个事件:Loaded和Initialized事件。当控件被加载到页面上的
时候,这两个事件会相继发生, 那么这两个事件的差别是什么哪?在进行自定义控件开发的时候,应该如何使用这两个事件那?
小结:
- Initialized事件:该事件表明Frameworkelement已经被创建, 而且它的所有属性已经被设置。通常情况下子Element的事件会先于父Element触发,当Element接到该事件的时候,只 是说明其sub-tree已经被初始化,而父Element还没有被初始化。当Element的XMAL sub-tree被加载的 时候,该事件会被触发,这个时候FrameworkElement的IsInitialized属性为True。
- Loaded事件:该事件表明Frameworkelement 不但被创建,初始化,而且该Element已经被加载到VirtualTree上,接下来该Element将被Render。从根节 点开始,该事件会以广播的方式在子Element触发,这个时候,FrameworkElement的IsLoaded属性为 True。
Initialized事件
Initialized事件标示当前Element的所有属性都已经被设置。WPF中 FrameworkElement实现了ISupportInitialize接口,当EndInit方法被调用的时候,置 IsInitialized属性为True,然后触发Initialized 事件。
ISupportInitialize接口允许开发人员在控件的
BeginInit后推迟某些属性的设置,直至EndInit时机才统一进行
多个属性的设置。利用ISupportInitialize接口可以解决由于属性设置顺序以及属性之间相互约束产生的问题。
WPF的XAML Loader已经支持了ISupportInitialize接口,创建完成对象后(解析完对象的开始节点),会调用
BeginInit方法,当加载完成该对象的XAML tree之后(解析完对象的结束节点)回调用EndInit方法。
如下面的例子:
< Button Width="100"> Hello World! </ Button > |
Button被创建的时候,BeginInit被调用,然后Width属性被设置,Content 属性被设置,最后EndInit方法被调用。
另外一件事情是在Initialized之前Element的隐式Style不会被应用,如下面的例
子:在Button类型的Style中定义了Background为Blue,但是Button1对象在Initialized之前它的Background为Null。
< Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" > < Page.Resources > < Style TargetType="Button"> < Setter Property="Background" Value="Blue" /> </ Style > </ Page.Resources > < Button Name="Button1">Clack</ Button > </ Page > |
如果使用代码来创建FrameworkElement对象,同时也没有调用该对象的BeginInit和EndInit方法,那么在该对象被添加到VisualTree上的时候,Initialized事件会被触发。
Initialized事件是自底向上触发,由父向子。通常情况下只有子对象被初始化之后,父对象才应该被初始化。
Loaded事件
FrameworkElement的Loaded事件被触发的时候,该对象已经被初始化,而且即 将被绘制。开发人员可以在该事件中进行一些应用程序的初始化工作。
Initialized事件也可以做一些初始化的事情,但是在该事件中Element的有一些属性是不准确的,例如ActualWidth和
ActualHeight,因为该对象仅仅是被初始化,还没有开始计算ActualWidth和ActualHeight,一些数据绑定
的属性也还没有开始计算。
Loaded事件通常会在第一次Render之前触发,Element已经被Layout,数据
绑定也已经被计算。需要注意的是如果你在Loaded中Invalidate了Layout,在Render之前该事件有可能会被重新触
发。
Loaded事件是自顶向下以广播方式触发,从根节点,由父向子触发。而Initialized
事件是自底向上触发,先子后父。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端