简体   繁体   English

WinForms中的按钮具有CLICK事件。 但是谁告诉按钮对象已被单击呢?

[英]The Button in WinForms has a CLICK event. But who tells the Button object that it has been clicked?

I am learning C#. 我正在学习C#。 I was going through the Events and Delegates part of the language. 我正在浏览语言的“事件和代表”部分。 I am working on a WinForms application for educating myself. 我正在使用WinForms应用程序进行自我教育。 I tried looking deep for understanding Buttons and how they work. 我试图深入了解Buttons及其工作方式。 I found the following: 我发现以下内容:

1) There is a line public partial class Form1 : Form in my default Form1.cs file. 1)在我的默认Form1.cs文件中有一个public partial class Form1 : Form This is a partial class. 这是局部类。

2) I also have a Form1.Designer.cs class file that has a line partial class Form1 . 2)我也有一个Form1.Designer.cs类文件,其中有一行partial class Form1 Now the files mentioned in 1) and 2) combine to form a full class. 现在,在1)和2)中提到的文件合并在一起形成一个完整的类。

3) The From1.Designer.cs file has a lot of statements that eventually create the button object. 3)From1.Designer.cs文件包含许多最终创建按钮对象的语句。 It also has a statement that is of particular interest to me: 它也有我特别感兴趣的声明:

 this.btn_BaseBuildLocation.Click += new System.EventHandler(this.btn_BaseBuildLocation_Click); 

This statement adds a custom function to the delegate Click. 该语句将一个自定义函数添加到委托Click。 This delegate is declared in the Control class (System.Windows.Forms.dll) as follows: 在Control类(System.Windows.Forms.dll)中声明此委托,如下所示:

 public event EventHandler Click; 

4) The EventHandler is a delegate defined in System.EventHandler.cs (mscorlib.dll). 4)EventHandler是在System.EventHandler.cs(mscorlib.dll)中定义的委托。

5) The Button class inherits Control class and thus has access to the Click EventHandler. 5)Button类继承了Control类,因此可以访问Click EventHandler。

6) The Button class has all the logic to handle the flow once it knows that someone has clicked it. 6)一旦知道有人单击了Button类,它就具有处理该流的所有逻辑。 I had a look at the Button class used in Mono for understanding the inner details. 我看了一下Mono中用于了解内部细节的Button类。 I do this for almost all classes that I want to learn. 我对几乎所有我想学习的课程都这样做。

7) All this is extremely beautiful. 7)这一切都非常美丽。 But I was troubled by the fact that I did not know how the Button object knows that it has been clicked. 但是我不知道Button对象如何知道它已被单击,这一事实使我感到困扰。

8) I went through VC++ and how it handles the events. 8)我经历了VC ++及其如何处理事件。 I found a lot about Message Loops, Event Queues etc... 我发现了很多有关消息循环,事件队列等的信息。

Questions: 问题:

1) Is the VC++ way of handling events the same as .NET's? 1)VC ++处理事件的方式是否与.NET相同?

2) If so, is there a way to look into those details? 2)如果是这样,是否有办法研究这些细节?

Any help would be appreciated. 任何帮助,将不胜感激。 Thanks. 谢谢。

A Button is, technically, a Window. 从技术上讲,按钮是窗口。 It has a Window handle. 它具有窗口句柄。

That means that the Dispatcher will route keyboard and mouse events to the Button when appropriate. 这意味着分派器将在适当的时候将键盘和鼠标事件路由到按钮。 The Button has internal logic to determine when a MouseDown and a MouseUp event constitute a valid click and then it raises the Click event. Button具有内部逻辑,可以确定MouseDown和MouseUp事件何时构成有效的单击,然后引发Click事件。

  1. 1) Is the VC++ way of handling events the same as .NET's?

    Yes obviously, handling is same, it is done by capturing the window messages and respond accordingly. 是的,显然,处理是相同的,它是通过捕获窗口消息并做出相应的响应来完成的。 .Net provides a wrapper around window handles 'NativeWindow class' which is low level encapsulation of a Window Handle , System.Windows.Forms.Control is the base class for all Controls which internally uses decendant of NativeWindow named ControlNativeWindow which passes all Messages to Control. 达网络提供围绕窗口句柄“NativeWindow类”,这是一个低电平封装的封装Window Handle ,System.Windows.Forms.Control的是所有控件的基类,其在内部使用的decendant NativeWindow命名ControlNativeWindow其传递所有消息来控制。

  2. If so, is there a way to look into those details? 如果是这样,是否有办法研究这些细节?

    Yes, dig into Control class Through Reflector 是的,通过Reflector进入Control类

hope this helps 希望这可以帮助

In WinForm appplicatio you have Program class with Main method. 在WinForm应用程序中,您具有带有Main方法的Program类。 There is always one line there: 那里总是有一行:

Application.Run(new YourMainForm());

It begins running a standard application message loop on the current thread. 它开始在当前线程上运行标准应用程序消息循环。 That's the "starting point" for events. 这是事件的“起点”。

Answer to this question explains it prertty well and also links to some sources 这个问题的答案很好地解释了它,并且还链接到一些资料来源

A WinForms Button is a managed wrapper around the unmanaged Windows type which is created and managed via a set of Win32 API calls that .NET performs P/Invoke on. WinForms Button是围绕非托管Windows类型的托管包装,该Windows类型是通过.NET在其上执行P / Invoke的一组Win32 API调用创建和管理的。

Deep down, the button subscribes to the same Window Event Loop (or Message Pump if you prefer) which drives the Win32 API calls you may have seen in VC++ examples. 在最深处,该按钮订阅了相同的窗口事件循环(或消息泵,如果您愿意的话),该窗口事件循环驱动您可能在VC ++示例中看到的Win32 API调用。 The unmanaged Windows runtime puts events (like "this button has been clicked") onto the event queue. 非托管Windows运行时会将事件(例如“已单击此按钮”)放入事件队列。 When the loop executes, the queued event is picked up by the relevant control and is propagated into a "managed" event which is when you are able to observe it. 当循环执行时,排队的事件由相关控件拾取,并传播到“托管”事件中,即您能够观察到的事件。

In essence, the Windows runtime is providing much of the infrastructure and .NET only provides a convenient set of wrappers which make it easy to work with the clunky old Win32 libraries. 本质上,Windows运行时提供了许多基础结构,.NET仅提供了一组方便的包装器,这使使用笨拙的旧Win32库变得容易。

You can discover a lot of this for yourself if you use Reflector and dig into Button and Control to just see where the .NET code ends and the unmanaged Win32 calls begin. 如果您使用Reflector并深入研究Button and Control以查看.NET代码在何处结束,以及不受托管的Win32调用开始,您会发现很多事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM