是否有类似于Form.Shown的形式生命周期?

时间:2014-07-23 19:16:36

标签: c# .net winforms layout redraw

了解我可以使用Forms.Shown event在第一次完全显示表单时收到通知,我发现在形式的生命周期中我还没有找到类似的东西。

即。考虑添加/删除控件或调整表单大小。

我考虑过注册Application.Idle event并以某种方式将其与我的表格联系起来,但我不确定这是否是正确的方法。

此外,我还考虑了对LayoutEngine class进行子类化以获取对某些事件/覆盖的访问权限。再一次,这看起来并不适合我。

所以我的问题是:

当表单已经可见时以编程方式添加/删除/调整控件大小时,如何检测表单何时完全完成布局和绘图?

3 个答案:

答案 0 :(得分:3)

  

即。考虑添加/删除控件或调整表单大小

不,当用户可以看到窗口时,从不想要这样做。在用户可以看到你对窗口进行修改时,有两个基本的地方想要编写像这样的代码,实际上看到它改变了大小,四处移动并且因为多个Paint事件而疯狂地闪烁。 / p>

首先是你的类构造函数。这就是你在.NET中初始化对象的地方,添加或删除控件属于那里。

Secondary是Load事件。这个事件通常很难理解,并且经常在Winforms中使用 way 。由它作为Form类的默认事件引发,这是一个历史事故,可以追溯到早期版本的Visual Basic,它是用于初始化表单的事件。这不再合适,.NET类对象应该在它们的构造函数中初始化。

当您的代码需要知道窗口的位置或大小时,加载或者更确切地说OnLoad()是合适的。那时需要发生在本机窗口的所有内容都已完成。它具有有效的Handle属性,Windows选择了一个位置,如果需要重新调整以适应机器的DPI设置,其Size属性现在有效,反映缩放和任何用户首选项,布局已执行,因此每个控件都在其预期位置。尚未发生的唯一事情是尚未触发Paint事件。因此,窗口尚未对用户可见。这在Load完成后很快就会发生。

因此,在OnLoad中调整或移动窗口通常是合适的,因为您现在知道实际大小和位置。请注意DPI重新缩放,不要硬编码大小。

如果您需要在显示窗口后的某个固定时间运行代码,那么Timer是合适的。

答案 1 :(得分:1)

我在这里猜测,但表格的OnPaint事件可能会起作用。您可以覆盖基础OnPaint处理程序,调用父函数,然后放置您之后的任何逻辑。

答案 2 :(得分:1)

您可以为调用常用函数的每个事件使用单独的事件调用

即。 ResizeEnd用于调整大小,ControlAdded和ControlRemoved用于控件。

private void Form1_ResizeEnd(object sender, EventArgs e)
{
    DoWork()
}

private void Form1_ControlAdded(object sender, ControlEventArgs e)
{
   DoWork()
}

private void Form1_ControlRemoved(object sender, ControlEventArgs e)
{
   DoWork() 
}

private void DoWork()
{
  //What needs to be done for each of them
}

我不确定这些电话的时间安排。