我对C#中控件应用程序事件的理解:
创建一个与订阅者类中的事件处理程序方法具有相同签名的委托。
根据此委托声明一个事件
举起活动 我对这一步骤的理解是:它只是一个包装函数,其中参数被传递给事件以调用事件指向的事件处理函数。
因此,引发事件只是调用发布类中的包装器函数。
现在,当我创建一个非常简单的Windows窗体应用程序时,我无法应用这个一般概念。
只需一个按钮即可考虑使用WinForms应用程序。
// registering statement
Button1.Click += new EventHandler (this.button1_click)
我可以确定第一步。它是预定义的System.EventHandler委托。
按钮的点击事件也是预定义的。没问题。
事件提升步骤:此处我无法在控制台应用程序和Windows应用程序之间建立连接。
保存的代码在哪里实际上为WinForms应用程序提升了事件?我们似乎不必编码。
我理解点击事件是在某人"点击"在按钮上,但是如何在WinForms应用程序的C#代码中实现?
编译器如何"只是"知道按钮的Click事件意味着有人点击了一个按钮,因此应该引发一个事件吗?
点击事件是如何引发的?参数如何传递给事件?
答案 0 :(得分:5)
Control
类具有受保护的函数WndProc
,当操作系统需要告诉程序它生成一个Message
对象并将其传递给WndProc
函数时。
WndProc
函数然后查看消息并查看它是什么类型的消息,如果它是“mouse left button up”消息,它使用正确的参数运行OnClick
方法解析出传递给Message
的{{1}}对象。
WndProc
方法将事件提升给订阅者。
来自.NET的理解:
答案 1 :(得分:1)
你的理解有点倒退。我认为这就是你遇到问题的原因。
您不创建与订阅者类中的事件处理程序方法具有相同签名的委托。
您正在做的是声明委派执行的功能将是什么样的。这是EventHandler的签名:
public delegate void EventHandler(object sender, EventArgs e)
因此,如果您希望函数能够处理事件的委派,则必须遵循该签名。
现在,将执行委托给订阅者的类需要对这些函数的引用,以便在事件发生时调用它们。这就是您实现事件属性的原因。接下来,Button类必须公开此属性,以便能够“挂钩”您的代理:
public event EventHandler Click
(注意这是从Control继承的)
注册“事件处理程序”时:
Button1.Click += new EventHandler (this.button1_click)
你基本上是说要在Button1实例引发Click事件时触发this.button1_click(object sender, EventArgs e)
。
Button1实例将在内部决定何时触发事件,此时它将使用event属性将执行委托给订阅的函数。它将使用上述参数调用它们,其中sender很可能是实例本身,EventArgs类将为您提供有关引发事件的条件的其他信息。该属性通常也用于添加额外的检查(例如,如果首先要调用任何内容)。
正如您所看到的,实际引发单击的代码是Button(或其继承链)实现的内部代码。它显然涉及鼠标跟踪和什么不是,顺便使用控件的好处,除非你想从头开始编写所有检测内容。