VB.NET里面的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 As EventArgs)
Private Sub MyButton_Click(ByVal sender As Object, ByVal e As System.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 As System.EventArgs) Handles MyClass1.MyEvent
Console.WriteLine("MyEvent ... ")
End Sub
Private Sub MyClass1_MyExtendedEvent(ByVal sender As Object, ByVal e 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 As System.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 As Object, ByVal e As EventArgs, ByRef Cancel As Boolean)
现在Event通过一个ByRef Cancel As Boolean参数将用户的要求返回回来。这样我们就可以在MyClass1里面知道了用户有什么要求。如果Cancel=True的时候,表明了用户希望终止这个事件之后的所有操作。这样我们的调用函数就变成。
Private Sub MyButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyButton.Click
Dim blnCancel As Boolean = False
RaiseEvent MyEvent(Me, New EventArgs, blnCancel)
If blnCancel = False Then
ExtendedCommand()
End If
End Sub
这样使用者使用这个事件的时候,就可以控制这个事件之后的操作了。
Private Sub MyClass1_MyEvent1(ByVal sender As Object, ByVal e As System.EventArgs, ByRef Cancel As Boolean) Handles MyClass1.MyEvent
If m_blnGo = True Then
Console.WriteLine("MyEvent ... ")
Else
Cancel = True
End If
End Sub
如果用户不希望操作,那么他通过Cancel = True就可以把此后的操作都撤销掉。
这样的操作在我们制作工具控件的时候特别有用,比如我们在Button.Click的时候显示一个默认的字符串,但是用户可以修改是否显示、内容,这时候用这种方法最为合适。
我们定义一个Event,通过参数传递Cancel和Message。如果Cancel为False的时候,我们就把Msg显示出来。
Public Class ShowMessage
Inherits Object
Public Event ShowMessage(ByVal sender As Object, ByVal e As EventArgs, ByRef Cancel As Boolean, ByRef Message As String)
Private Const CST_MSG As String = "This is default message."
Private WithEvents Button1 As New Button
Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim Cancel As Boolean = False
Dim Msg As String = CST_MSG
RaiseEvent ShowMessage(Me, New EventArgs, Cancel, Msg)
If Cancel = False Then
MsgBox(Msg)
End If
End Sub
End Class
而Cancel和Msg的内容,我们实现给定了默认值,由用户来决定。如果用户什么都不做,那么就是显示默认的内容了。
Public Class TestShowMessage
Inherits Object
Friend WithEvents ShowMessage1 As New ShowMessage
Private m_blnNeedShow, m_blnCustomShow As Boolean
Private Sub ShowMessage1_ShowMessage(ByVal sender As Object, ByVal e As System.EventArgs, ByRef Cancel As Boolean, ByRef Message As String) 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自己是怎么做的。
- 未完待续 -