2009-05-19 49 views
3

好吧,所以我有一個基類聲明事件StatusTextChanged。我的孩子班當然不能直接舉辦這個活動。基類中的事件

所以我風與像這樣(爲簡單起見):

Public MustInherit Class FooBase 
    Public Event StatusTextChanged(ByVal StatusText As String) 
    Protected Sub RaiseStatusTextChangedEvent(ByVal StatusText As String) 
     RaiseEvent StatusTextChanged(StatusText) 
    End Sub 
End Class 

然後在子類我稱之爲 MyBase.RaiseStatusTextChangedEvent("something")。 有沒有更好或更推薦的方法來做到這一點?

編輯:VB.NET或C#,無論哪種方式,它的工作原理基本相同。

編輯:所以響應後,我在這個基類,那麼就設置在子類的狀態文本屬性...

Public Event StatusTextChanged(ByVal StatusText As String) 
    Private _StatusText As String = "Idle." 
    Public Property StatusText() As String 
     Get 
      Return _StatusText 
     End Get 
     Protected Set(ByVal value As String) 
      RaiseEvent StatusTextChanged(value) 
     End Set 
    End Property 
+0

正如弗雷德裏克指出狀態文本參數編碼,你拿出的辦法是非常接近.NET框架標準。看看System.Windows.Forms.TextBox,你會看到很多保護的虛擬方法(OnTextChanged等),只是爲了這個目的 – 2009-05-19 15:13:27

+0

可重寫的位是完全可選的ofc,只有當你需要改變行爲子類。 – 2009-05-19 15:15:22

+0

在我看來,你的示例代碼中缺少一行,儘管..並不是說它對事件引發問題本身而言很重要,但爲了完整起見,也許你應該在「事件提交問題」之後插入「_StatusText = value」設置(ByVal值爲字符串)「行。事實上,甚至可以將它全部包裝在「If value <> _StatusText Then」等中,以確保StatusTextChanged事件不會被引發,除非狀態文本實際上是*更改:) – d7samurai 2012-09-28 16:52:59

回答

6

我會說你比較接近推薦方式(或者至少我會推薦的方式)。

我會做一些改動你的代碼,給出一個選擇:

  • 製作StatusTextChanged Protected Overridable
  • 包裹狀態文本在自定義EventArgs類
  • 更改StatusTextChanged聲明爲Public Event StatusTextChanged As EventHandler(Of YourCustomEventArgs)

生成的代碼:

自定義EventArgs類:

Public Class TextEventArgs 
    Inherits EventArgs 

    Private _text As String 

    Public Sub New(ByVal text As String) 
     _text = text 
    End Sub 

    Public ReadOnly Property Text() As String 
     Get 
      Return _text 
     End Get 
    End Property 

End Class 

在基類中的事件實現:

Public Event StatusTextChanged As EventHandler(Of TextEventArgs) 
Protected Overridable Sub OnStatusTextChanged(ByVal e As TextEventArgs) 
    RaiseEvent StatusTextChanged(Me, e) 
End Sub 

...終於爲引發事件的代碼行;無論是在基類還是繼承它的類:

OnStatusTextChanged(New TextEventArgs("some text")) 

這將更符合在.NET框架的其餘部分中設計事件的方式。你可以有

1

除非對你的孩子特別需要類來重寫基類方法,那麼我會說調用基類實現絕對是最好的解決方案。

+0

澄清,你的意思是我做這件事是最好的解決方案嗎?似乎有點冗餘代碼。沒有重寫,至少不是我喜歡的,但我不能聲明它NotOverridable,因爲它不覆蓋基礎方法(它在基類中)。我應該澄清這個問題嗎? – hmcclungiii 2009-05-19 14:50:33

0

這幾乎是在這種類型的場景中通過派生類提升基類上的事件的標準方式。

然而,這可能會改變一點,這取決於誰控制着層次結構的StatusText。如果FooBase中只有一個具體的StatusText支持字段可以通過訪問器進行更改,那麼我不會讓子控制StatusTextChanged事件的發生。相反,我會強制在StatusText屬性的Setter中引發事件。這使得父類在執行它想要的任何合約時可以更多地控制何時以及何時不提出該事件。

但是,如果StatusText是必須由派生類定義的屬性,我會選擇您顯示的路線。

0

一種選擇是包裹狀態屬性的基類,所以它提出了一個變化 事件本身(在C#作爲不知道VB和不具有的時刻訪問到Visual Studio)

private string _status; 

public string Status 
{ 
    get { return _status; } 
    protected set 
    { 
     if (_status == value) return; 
     _status = value; 
     StatusChanged(value); 
    } 
} 
0

,這裏是我的一個代表一個事件,

 
Public Event Status As StatusEventHandler 

Protected Overridable Sub OnStatus(ByVal e As StatusEventArgs) 
    RaiseEvent Status(Me, e) 
End Sub 

Public Delegate Sub StatusEventHandler(ByVal sender As Object, _ 
    ByVal e As StatusEventArgs) 

<System.Serializable()> _ 
Public Class StatusEventArgs 
    Inherits System.EventArgs 

    Public Sub New() 
    End Sub 

    Public Sub New(ByVal statusText As String) 
     _StatusText = statusText 
    End Sub 

    ' Enter code here for event properties, etc. 

    Private _StatusText As String = "" 
    Public Property StatusText() As String 
     Get 
      Return _StatusText 
     End Get 
     Set(ByVal value As String) 
      _StatusText = value 
     End Set 
    End Property 


End Class