在Windows窗体中加载与显示的事件 [英] Load vs. Shown events in Windows Forms

查看:169
本文介绍了在Windows窗体中加载与显示的事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

希望我只是缺少一些显而易见的东西,但是我试图围绕着 Windows窗体



传统上,我只使用Load(或者实际上是OnLoad,因为我认为覆盖一个方法,而不是依靠设计人员自己挂接一个事件),因为在所有版本的.NET中都可以使用它。现在,如果您在MSDN文档中查看这些说明,请参见.NET Framework 2.0中的显示事件。



第一次,显示:每当表单首次显示时都会发生。)它会像Load事件应该发生,那么该表单应该可见,则显示的事件应该发生;两者的结合使得您可以在表单之前和之后执行一些任务。有意义的吧?



然而,实验表明,只要我尝试(而且两者都是),显示事件总是发生在 Load事件之前在表单变得可见之前发生)。但是,当我发现一个关于这些事件被触发的顺序的页面时,它们总是列出加载事件被首先触发。



我是只是疯了,还是我错过了什么? (如果他们确实发生在同一时间,那么为什么显示事件首先被添加?)



(我目前的解决方案,显示形式是使用OnLoad进行显示前的东西,并为后显示的东西开始一个短时间的单次计时器,哪个工作正常可靠,但是有点丑,我希望有一个更清洁的解决方案,但它看起来像显示的事件不是它。)

解决方案

避免使用MessageBox.Show()调试这个。它泵送消息循环,扰乱事件的正常流动。由Windows发送WM_SHOWWINDOW消息触发加载事件,就在窗口可见之前。没有Windows通知,您的窗口现在完全显示,所以WF设计师想出了一个技巧来生成显示事件。他们使用Control.BeginInvoke(),一旦程序再次空闲并重新进入消息循环,就可以确保OnShown()方法被调用。



这个技巧有许多其他用途,特别是当您必须延迟执行由事件开始的代码时。但是,在您的情况下,它会因为使用MessageBox.Show()而分崩离析。它的消息循环调度注册BeginInvoke()的代理,导致显示事件在之前显示窗口。



有很多其他方法可以在MessageBox之外获得诊断。 Debug.Print()和Console.WriteLine()很方便,他们的输出将转到 Visual Studio输出窗口,而不会对正常事件触发序列造成任何不利影响。一个简单的断点也可以做奇迹。


Hopefully I'm just missing something obvious, but I'm trying to get my head around the differences between the Load and the Shown events in Windows Forms.

Traditionally, I've only used Load (or actually OnLoad, since I think it's cleaner to override a method than to rely on the designer to hook up an event on yourself), since that is available in all versions of .NET. With .NET 2.0 the Shown event was introduced.

Now, if you look at the descriptions for these in the MSDN documentation ("Load: Occurs before a form is displayed for the first time.", "Shown: Occurs whenever the form is first displayed.") it sounds like the Load event should occur, then the form should become visible, then the Shown event should occur; the combination of the two thereby letting you carry out some tasks both before and after the form is visible. Makes sense, right?

However, experimentation has shown that the Shown event invariably occurs before the Load event, whenever I try it (and both occur before the form becomes visible). And yet, when I google around whenever I discover a page that talks about the order these events are fired in, they always list the Load event being fired first.

Am I just going crazy, or have I missed something? (And if they do occur at about the same time, then why was the Shown event added in the first place?)

(My current solution for doing something both before and after showing the form is to use OnLoad for the "before showing" stuff and start a short-duration one-shot timer for the "after showing" stuff. Which works OK and reliably, but it's a bit ugly and I was hoping there was a cleaner solution. But it looks like the Shown event isn't it.)

解决方案

Avoid using MessageBox.Show() to debug this. It pumps a message loop, disturbing the normal flow of events. The Load event is triggered by Windows sending the WM_SHOWWINDOW message, just before the window becomes visible. There is no Windows notification for "your window is now fully shown", so the WF designers came up with a trick to generate the Shown event. They use Control.BeginInvoke(), ensuring the OnShown() method gets called as soon as the program goes idle again and re-enters the message loop.

This trick has lots of other uses, particularly when you have to delay the execution of code started by an event. However, in your case it falls apart because you use MessageBox.Show(). Its message loop dispatches the delegate registered with BeginInvoke(), causing the Shown event to run before the window is shown.

There are lots of other ways to get diagnostics beyond MessageBox. Debug.Print() and Console.WriteLine() are handy, their output goes to the Visual Studio Output Window without having any detrimental effects on the normal event firing sequence. A simple breakpoint can do wonders too.

这篇关于在Windows窗体中加载与显示的事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆