C#winform窗体句柄啥时候创建及窗体创建事件顺序)
前言
在项目中遇见实例化窗体类后,使用invoke报错的情况,做以下测试。
测试
1.窗体类实例化之后
代码如下:
两个基本的winform窗体,在第一个窗体的载入事件中编写:
form1:
using System;
using System.Windows.Forms;
namespace WinformHandleTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Form2 form = new Form2();
Console.WriteLine("form窗体句柄是否被创建:"+ form.IsHandleCreated.ToString());
}
}
}
form2:
using System;
using System.Windows.Forms;
namespace WinformHandleTest
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
}
}
运行结果:
窗体类实例化之后并不会创建
2.form.show()之后
form1加载中的代码:
private void Form1_Load(object sender, EventArgs e)
{
Form2 form = new Form2();
Console.WriteLine("form窗体句柄是否被创建:"+ form.IsHandleCreated.ToString());
form.Show();
}
为方便看清窗体加载显示的过程顺序,我为窗体多个事件添加打印,代码冗余在此不做展示,结果如下:
红线上部分就是没有show之前,句柄都未被创建,进入show(下部分)时立即被创建。
PS:
从上图可以看到窗体show()时,大致的事件顺序为:
事件说明 | 事件名称 |
---|---|
1.创建窗体句柄 | HandleCreated |
2.上下文绑定改变 | BindingContextChanged |
3.窗体加载 | Load |
4.隐藏属性改变 | VisibleChanged |
5.窗体成为活动窗体 | Activated |
6.窗体第一次显示 | Shown |
3.另外Application.Run();
Application.Run()常在程序入口处,说明如下:
//
// 摘要:
// 在当前线程上开始运行标准应用程序消息循环,并使指定窗体可见。
//
// 参数:
// mainForm:
// 一个 System.Windows.Forms.Form,它代表要使之可见的窗体。
//
// 异常:
// T:System.InvalidOperationException:
// 主消息循环已在当前线程上运行。
public static void Run(Form mainForm);
以此函数运行时结果:
与自行实例化窗体后show出来,大致顺序相同。
总结
故窗体通过show()函数或者Application.Run()运行时,窗体才获得句柄,并通过打印可看见句柄创建位于整体顺序的那个位置。