VB.NET中的Event机制

VB.NET中的Event机制,第1张

概述自从VB6开始,Event这个东西就已经深入了VB系列程序中间。在VB6中,我们是简单的通过诸如TextBox1_TextChanged这样一个函数了解到当文字变化的时候,就能够自动触发这个函数。进入了.NET之后,是我们有幸第一次看到了Event的真面目。现在我们在VB.NET里面直接写入下面的函数     Private SubTextBox1_TextChanged(ByVal sender

自从VB6开始,Event这个东西就已经深入了VB系列程序中间。在VB6中,我们是简单的通过诸如TextBox1_TextChanged这样一个函数了解到当文字变化的时候,就能够自动触发这个函数。进入了.NET之后,是我们有幸第一次看到了Event的真面目。现在我们在VB.NET里面直接写入下面的函数
Private SubTextBox1_TextChanged(ByVal sender As System.Object,ByVal e AsSystem.EventArgs) Handles TextBox1.TextChanged

End Sub

看来是不能够达到VB6的效果的。原因是我们少写了HandlesTextBox1.TextChanged。
这个就是真实存在的Event了。VB.NET对于Event终于可以脱离了函数名的限制(但是不是函数的全部限制),自由的使用。只要我们喜欢,我们也可以写成
Private SubThisIsMyTextChangedMethod(ByVal sender As System.Object,ByVal e AsSystem.EventArgs) Handles TextBox1.TextChanged

End Sub

完全可以。
现在我们就来看看我们如何在自己的类里面加入我们需要的Event。

(1)首先我们需要一个类
Public Class Class1

inheritsObject

End Class


(2)然后我们就可以在这个类里面加入我们的Event了。

Public Class Class1

inheritsObject

Public EventMyEvent(ByVal sender As Object,ByVal e As EventArgs)

End Class

Event里面是可以携带参数的。就好像TextChangedEvent一样,他携带了sender和e。sender表示这个Event触发源的实例,也就是这个TextBox1;e是一个事件参数,我们可以将需要传达给使用的信息通过继承自EventArgs的类的实例来传递出去。而这里,EventArgs里面并没有什么有价值的信息。

现在这个类里面已经有了我们要的Event,但是这个Event仅仅是一个声明。也就是说,我们告诉编译器和使用者,Class1里面有一个叫做MyEvent的Event。我们的下一个步骤就是确定什么时候,我们要引发这个Event。

(3)引发Event的语句很简单。

RaiseEvent MyEvent(Me,New EventArgs)

但是值得我们注意的是,Event是不能凭空触发的。我的意思是,RaiseEvent也是一条VB语句,我们只能将这条语句写在Function、Sub或者Property里面。这就意味着我们的Event的触发,要么是通过别人调用了某一个方法,要么通过现在已经存在HandleSub来触发。

现在我们使用第一种方法,我们通过一个Public函数来触发这个Event。

Public SubDoSomething()

RaiseEvent MyEvent(Me,New EventArgs)

End Sub

这就意味着,当用户调用了DoSomething方法的时候,Class1就会自动抛出一个MyEvent事件出来。

到这里,一个完整的Event就已经做完了。很简单吧。

(4)同样的方法,我们可以在一个Handle Sub里面抛出我们Event。

Public Class Class1

inheritsObject

PrivateWithEvents Mybutton As New button

Public EventMyEvent(ByVal sender As Object,ByVal e As EventArgs)

Private SubMybutton_Click(ByVal sender As Object,ByVal e As System.EventArgs)Handles Mybutton.Click

RaiseEvent MyEvent(Me,New EventArgs)

End Sub

End Class

这里我们同过一个WithEvents的成员Mybutton的Click事件函数,触发我们自己的MyEvent事件。

(5)使用这个Class1,我们就可以看到我们自己做的这个MyEvent事件了。

Public Class Test

inheritsObject

PrivateWithEvents MyClass1 As Class1

Private SubMyClass1_MyEvent(ByVal sender As Object,ByVal e AsSystem.EventArgs) Handles MyClass1.MyEvent

End Sub

End Class

很简单吧,但是使用Event并不止如此。随后我们将会看到这样简单的使用Event会导致的一些问题。


现在我们看看下面的类。

Public Class Class1

inherits Object

Private WithEvents Mybutton As New button

Public Event MyEvent(ByVal sender As Object,ByVal e As EventArgs,ByRef Cancal As Boolean)

Public Event MyExtendedEvent(ByVal sender As Object,ByVal e AsEventArgs)

Private Sub Mybutton_Click(ByVal sender As Object,ByVal e AsSystem.EventArgs) Handles Mybutton.Click

Dim blnCancel As Boolean = False

RaiseEvent MyEvent(Me,New EventArgs,blnCancel)

ExtendedCommand()

End Sub

Private Sub ExtendedCommand()

RaiseEvent MyExtendedEvent(Me,New EventArgs)

End Sub

End Class

我们定义了两个Event,一个是MyEvent,另一个是MyExtendedEvent。我们在button.Click的时候,触发了我们的MyEvent,随后我们通过调用ExtendedCommand函数触发下一个Event。看来没有什么问题,用户在使用的时候,依照往常一样。

Public Class Test

inherits Object

Private WithEvents MyClass1 As Class1

Private Sub MyClass1_MyEvent(ByVal sender As Object,ByVal e AsSystem.EventArgs) Handles MyClass1.MyEvent

Console.Writeline("MyEvent ... ")

End Sub

Private Sub MyClass1_MyExtendedEvent(ByVal sender As Object,ByVale As System.EventArgs) Handles MyClass1.MyExtendedEvent

Console.Writeline("MyExtendedEvent ... ")

End Sub

End Class

看来一切都没有问题。但是我们有一个蹩脚的用户有这样的要求,他希望按照一个判断,确定是否执行MyEvent的后续 *** 作。并且如果不执行后续 *** 作的话,也不要引发MyExtendedEvent这个事件。

现在看看我们怎么做呢?我们可以简单的实现第一个要求,就在MyClass1_MyEvent函数里面加入一些判断就可以了。

Private Sub MyClass1_MyEvent(ByVal sender As Object,ByVal e AsSystem.EventArgs) Handles MyClass1.MyEvent

If m_blnGo = True Then

Console.Writeline("MyEvent ... ")

End If

End Sub

但是我们的第二个问题就没有办法解决了,因为无论我们在MyClass1_MyEvent下面做了多少工作,程序都回执着的回到RaiseEvent那条语句,然后执行ExtendedCommand,进而触发了MyExtendedEvent事件。所以这时候,我们应该回头看看我们的类是不是有些问题了。

我们的问题确实存在,就是我们在button.Click后无条件的RaiseEvent了。使用者没有办法阻止这一切的发生。他们能做的就是在RaiseEvent的时候加入一些 *** 作,但是无论如何不能修改我们原先的 *** 作。这看来着实让人沮丧,就好像订阅短信之后无法退订一样。现在我们看看怎么来解决这个问题,就是说我们提供给使用者功能的同时,我们还应该提供给他们如何取消这些功能的办法(虽然这个功能可能很好)。

我们首先把着眼点放在了Event的参数里面,我们可以通过参数将一些信息传递给用户,自然我们也能供通过参数将用户的要求反馈回来。

我们这样修改我们的程序。

Public Event MyEvent(ByVal sender AsObject,ByRef Cancel As Boolean)

现在Event通过一个ByRef Cancel AsBoolean参数将用户的要求返回回来。这样我们就可以在MyClass1里面知道了用户有什么要求。如果Cancel=True的时候,表明了用户希望终止这个事件之后的所有 *** 作。这样我们的调用函数就变成。

Private Sub Mybutton_Click(ByVal sender As Object,blnCancel)

If blnCancel = False Then

ExtendedCommand()

End If

End Sub

这样使用者使用这个事件的时候,就可以控制这个事件之后的 *** 作了。

Private Sub MyClass1_MyEvent1(ByVal sender As Object,ByVal e AsSystem.EventArgs,ByRef Cancel As Boolean) HandlesMyClass1.MyEvent

If m_blnGo = True Then

Console.Writeline("MyEvent ... ")

Else

Cancel = True

End If

End Sub

如果用户不希望 *** 作,那么他通过Cancel =True就可以把此后的 *** 作都撤销掉。

这样的 *** 作在我们制作工具控件的时候特别有用,比如我们在button.Click的时候显示一个默认的字符串,但是用户可以修改是否显示、内容,这时候用这种方法最为合适。

我们定义一个Event,通过参数传递CancelMessage。如果CancelFalse的时候,我们就把Msg显示出来。

Public ClassShowMessage

inherits Object

Public Event ShowMessage(ByVal sender As Object,ByVal e AsEventArgs,ByRef Cancel As Boolean,ByRef Message Asstring)

Private Const CST_MSG As String = "This is defaultmessage."

Private WithEvents button1 As New button

Private Sub button1_Click(ByVal sender As Object,ByVal e AsSystem.EventArgs) Handles button1.Click

Dim Cancel As Boolean = False

Dim Msg As String = CST_MSG

RaiseEvent ShowMessage(Me,Cancel,Msg)

If Cancel = False Then

MsgBox(Msg)

End If

End Sub

End Class

CancelMsg的内容,我们实现给定了默认值,由用户来决定。如果用户什么都不做,那么就是显示默认的内容了。

Public ClasstestShowMessage

inherits Object

FrIEnd WithEvents ShowMessage1 As New ShowMessage

Private m_blnNeedShow,m_blnCustomShow As Boolean

Private Sub ShowMessage1_ShowMessage(ByVal sender As Object,ByVale As System.EventArgs,ByRef Message Asstring) Handles ShowMessage1.ShowMessage

If m_blnNeedShow = True Then

If m_blnCustomShow = True Then

Message = "This is custom message."

End If

Cancel = False

Else

Cancel = True

End If

End Sub

End Class

但是我们发现了一个新的问题,如果我们的参数很多很多,难道我们的Event就要无限的延长了么?我们这时候还是可以从参数来入手,看看.NET自己是怎么做的。

现在我们看看这样一个问题。我们想要做这样一个控件,他继承自Window.Forms.TextBox下面,也就是说它支持TextBox的所有功能,但是我们需要一个新的功能,就是当用户按下回车之后,我们判断一下这个TextBox里面的文字,如果是空字符串的话,就显示一个MessageBox,默认的内容是“Emptyconnect is notvalIDated.”。同时我们希望用户可以选择是否显示这个MessageBox。我们用此前的办法来做。

我们的类很快就可以完成。

Public ClassMyTextBox

inherits TextBox

Public Event EnterKeyPress(ByVal sender As Object,ByRef Cancel AsBoolean,ByRef Message As String)

Private Sub MyTextBox_KeyPress(ByVal sender As Object,ByVal e AsSystem.windows.Forms.KeyPressEventArgs) HandlesMyBase.KeyPress

'Do something then user press ENTER KEY

If Asc(e.KeyChar) = 13 Then

Dim Cancel As Boolean = False

Dim Message As String = "Empty connect is notvalIDated."

'Send the event with parameters

RaiseEvent EnterKeyPress(Me,Message)

'Show message Box depend on the return parameters

If Cancel = False Then

MsgBox(Message)

End If

End If

End Sub

End Class

而且我们很容易就可以使用这个控件了。

Public Class Form1

inherits System.windows.Forms.Form

#Region " windows FormDesigner generated code "

Public Sub New()

MyBase.New()

'This call is required by the windows Form Designer.

InitializeComponent()

'Add any initialization after the InitializeComponent()call

End Sub

'Form overrIDes dispose to clean up the component List.

Protected Overloads OverrIDes Sub dispose(ByVal disposing AsBoolean)

If disposing Then

If Not (components Is nothing) Then

components.dispose()

End If

End If

MyBase.dispose(disposing)

End Sub

'required by the windows Form Designer

Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the windows FormDesigner

'It can be modifIEd using the windows FormDesigner.

'Do not modify it using the code editor.

<System.Diagnostics.DeBUGgerStepThrough()>Private Sub InitializeComponent()

'

'Form1

'

Me.autoScaleBaseSize = New System.Drawing.Size(5,12)

Me.ClIEntSize = New System.Drawing.Size(292,273)

Me.name ="Form1"

Me.Text = "Form1"

End Sub

#End Region

FrIEnd WithEvents MyTextBox1 As New MyTextBox

Private Sub Form1_Load(ByVal sender As System.Object,ByVal e AsSystem.EventArgs) Handles MyBase.Load

Me.Controls.Add(Me.MyTextBox1)

Me.MyTextBox1.Location = New Point(100,100)

End Sub

Private Sub MyTextBox1_EnterKeyPress(ByVal sender As Object,ByRefCancel As Boolean,ByRef Message As String) HandlesMyTextBox1.EnterKeyPress

End Sub

End Class

现在看来一切正常,但是无聊的客户突然来了一个Mail,他们希望我们能够在显示MessageBox的时候,将TextBox的背景色变成红色,并且允许有可能在其它的时候会变成绿色。也就是说变色也是要使用者可以自由设定的。这样我们就要在Event参数列表里面加入一个新的背景色参数,并且修改所有使用了这个EventHandle函数。

Public ClassMyTextBox

inherits TextBox

Public Event EnterKeyPress(ByVal sender As Object,ByRef Message As String,ByVal Backcolor Ascolor)

Private Sub MyTextBox_KeyPress(ByVal sender As Object,ByVal e AsSystem.windows.Forms.KeyPressEventArgs) HandlesMyBase.KeyPress

'Do something then user press ENTER KEY

If Asc(e.KeyChar) = 13 Then

Dim Cancel As Boolean = False

Dim Message As String = "Empty connect is notvalIDated."

Dim color As color = color.Red

'Send the event with parameters

RaiseEventEnterKeyPress(Me,Message,color)

'Show message Box depend on the return parameters

If Cancel = False Then

MsgBox(Message)

End If

End If

End Sub

End Class

然后修改使用的地方,也许实际上我们只是让它显示成默认的红色,我们也需要修改使用Event的地方,因为Event的定义已经不同了。

Public Class Form1

inherits System.windows.Forms.Form

#Region " windows FormDesigner generated code "

Public Sub New()

MyBase.New()

'This call is required by the windows Form Designer.

InitializeComponent()

'Add any initialization after the InitializeComponent()call

End Sub

'Form overrIDes dispose to clean up the component List.

Protected Overloads OverrIDes Sub dispose(ByVal disposing AsBoolean)

If disposing Then

If Not (components Is nothing) Then

components.dispose()

End If

End If

MyBase.dispose(disposing)

End Sub

'required by the windows Form Designer

Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the windows FormDesigner

'It can be modifIEd using the windows FormDesigner.

'Do not modify it using the code editor.

<System.Diagnostics.DeBUGgerStepThrough()>Private Sub InitializeComponent()

'

'Form1

'

Me.autoScaleBaseSize = New System.Drawing.Size(5,273)

Me.name = "Form1"

Me.Text = "Form1"

End Sub

#End Region

总结

以上是内存溢出为你收集整理的VB.NET中的Event机制全部内容,希望文章能够帮你解决VB.NET中的Event机制所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/langs/1276763.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-09
下一篇 2022-06-09

发表评论

登录后才能评论

评论列表(0条)

保存