Question

Ok, so I have a base class which declares the event StatusTextChanged. My child class, of course cannot directly raise this event.

So I wind up with something like this (for simplicity sake):

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

And then in the child class I call MyBase.RaiseStatusTextChangedEvent("something"). Is there a better or more recommended way to do this?

edit: VB.NET or C#, either way it works essentially the same.

edit: So after the responses, I'm at this in the base class, then just set the StatusText property in the child class ...

    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
Was it helpful?

Solution

I would say that you are rather close to the recommeneded way (or at least the one I would recommend).

I would make a few alterations to your code, given a choice:

  • Make StatusTextChanged Protected Overridable
  • Wrap StatusText in a custom EventArgs class
  • Change the StatusTextChanged declaration into Public Event StatusTextChanged As EventHandler(Of YourCustomEventArgs)

The resulting code:

The custom eventargs class:

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

The event implementation in your base class:

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

...and finally a code line for raising the event; either in the base class or a class that inherits it:

OnStatusTextChanged(New TextEventArgs("some text"))

This will be more in line with how events are designed within the rest of the .NET framework.

OTHER TIPS

Unless there is a specific need for your child class to override a base class method then I would say that calling the base class implementation is absolutely the best solution.

This is pretty much the standard way for raising events on a base class via a derived one for this type of scenario.

However this could change a bit depending on who is in control of the StatusText for the hierarchy. If there is a concrete StatusText backing field in FooBase which can only be changed via accessors, then I would not let the child control the raising of the StatusTextChanged event. Instead I would force the raising of the events within the Setter of the property for StatusText. This gives the parent class more control in enforcing any contracts it wants around when to and when not to raise said event.

However if the StatusText is a property which must be defined by the derived class, I would choose the route you displayed.

One option you could have is wrap the Status property in the base class, so that it raises the event itself in a change (in C# as dont know VB and dont have access to Visual Studio at the moment)

private string _status;

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

Here's My code for an event with a delegate and a parameter of status text

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top