現在我們看看下面的類。
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自己是怎麼做的。