如何在继承阶梯上“跟随”属性更改事件

时间:2013-12-31 11:55:18

标签: vb.net winforms inheritance user-controls

我有一个用户控件,它将构成我打算在其上构建的其他复合用户控件的基础。在该基本控件中,我有一个下面定义的属性,其中包含与之相关的on change事件。

Private _themeToUse As String
Public Property ThemeToUse As String
    Get
        Return _themeToUse
    End Get
    Set(ByVal value As String)
        _themeToUse = value
        RaiseEvent ThemeToUseOnChange(Me, EventArgs.Empty)
    End Set
End Property

Public Event ThemeToUseOnChange(ByVal sender As Object, ByVal e As EventArgs)


Private Sub ThemeChanging(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.ThemeToUseOnChange
    ThemeController.Theme = ThemeToUse
End Sub

我想弄清楚的是我的新用户如何控制使用这个基本控件作为他们自己继承的控件可以利用on change事件。

我尝试将以下内容添加到我的新控件中,该控件在intellisense建议使用“阴影”之后继承基本控件,但它似乎没有被触发。

Shadows Event ThemeToUseOnChange(ByVal sender As Object, ByVal e As EventArgs)


Private Sub ThemeChanging(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.ThemeToUseOnChange
    C1ThemeController1.Theme = ThemeToUse
End Sub

任何人都可以告诉我应该如何正确地做这类事情吗?

由于

2 个答案:

答案 0 :(得分:1)

将此视为您的基类:

Public Class First

    Public Event ThemeToUseChanged As EventHandler
    Public Event ThemeToUseChanging As EventHandler

    Public Property ThemeToUse() As String
        Get
            Return Me.m_themeToUse
        End Get
        Set(ByVal value As String)
            If (value <> Me.m_themeToUse) Then
                Me.OnThemeToUseChanging(EventArgs.Empty)
                Me.m_themeToUse = value
                Me.OnThemeToUseChanged(EventArgs.Empty)
            End If
        End Set
    End Property

    Protected Overridable Sub OnThemeToUseChanged(ByVal e As EventArgs)
        If (Not Me.ThemeToUseChangedEvent Is Nothing) Then
            Me.ThemeToUseChangedEvent.Invoke(Me, e)
        End If
    End Sub

    Protected Overridable Sub OnThemeToUseChanging(ByVal e As EventArgs)
        If (Not Me.ThemeToUseChangingEvent Is Nothing) Then
            Me.ThemeToUseChangingEvent.Invoke(Me, e)
        End If
    End Sub

    Private m_themeToUse As String

End Class

这个类继承了First class:

中的所有内容
Public Class Second
    Inherits First

End Class

现在,您可以为每个对象的ThemeToUseChanged事件和ThemeToUseChanging事件添加句柄:

Public Class Form1

    Public Sub New()
        Me.InitializeComponent()
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        'Test:
        Me._first.ThemeToUse = New Guid().ToString()
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        'Test:
        Me._second.ThemeToUse = New Guid().ToString()
    End Sub

    Private Sub ThemeToUseChanged(sender As Object, e As EventArgs) Handles _first.ThemeToUseChanged, _second.ThemeToUseChanged
        If (sender Is Me._first) Then
            'ThemeToUseChanged changed of type `First`
        ElseIf (sender Is Me._second) Then
            'ThemeToUseChanged changed of type `Second`
        End If
    End Sub

    Private Sub ThemeToUseChanging(sender As Object, e As EventArgs) Handles _first.ThemeToUseChanging, _second.ThemeToUseChanging
        If (sender Is Me._first) Then
            'ThemeToUseChanging changed of type `First`
        ElseIf (sender Is Me._second) Then
            'ThemeToUseChanging changed of type `Second`
        End If
    End Sub

    Private WithEvents _first As New First
    Private WithEvents _second As New Second

End Class

如果您认为Third类继承了Second

Public Class Third
    Inherits Second

End Class

这是循环继承链的方法:

Dim obj As First = New Third()
Dim t As Type = obj.GetType()

Do
    MsgBox(t.FullName)
    t = t.BaseType
Loop Until (t.BaseType Is Nothing)

答案 1 :(得分:1)

似乎你应该将属性 value 作为事件的一部分,就像鼠标点击事件包括点击和鼠标信息一样:

Class ThemeChangedEventArgs
    Inherits EventArgs

    Public Proptery OldTheme As String
    Public Proptery NewTheme As String

    Sub New(oldT As String, newT AS String)
        OldTheme = oldT
        NewTheme = newT
    End Sub
 End CLass

 Public Event ThemeChanged(Sender as Object, e As ThemeChangedEventArgs)

然后:

Property Theme As String
 ...
 Set(value as string)

    RaiseEvent ThemeChanged(Me, New ThemeChangedEventArgs(_Theme, value))
    _Theme = Value
 End Set

该事件通常用于通知订阅者 - 如表格 - 主题已更改。它们也可用于从子类中冒泡信息,但这或多或少要求父级定义事件并首先了解属性。在这种情况下:

 Property Theme As String
 ...
 Set(value as string)
    MyBase.Theme = value

 End Set

假设该属性是在上游而不是在此类中定义的,那么这将告诉父类具有更少代码的相同事物。

使用事件进行房产变更的儿童更像是这样:

Class Parent
   ...
   Protected Friend MustOverride Property Theme() As String

   Public Event ThemeChanged ...

任何继承自Parent的类都需要定义Theme,因此它知道它,而不是细节。订阅者事件也在父级别定义,允许事件被实际实现它的任何类触发。

事件派上用场的是内部流程。有些东西发生在内心深处,因此一个类引发FooChange event,父类在OnFooChange中响应,执行类似计算更改的影响,然后可能会引发用户事件(对于表单),如{{ 1}}。 Child了解Foo,但Parent处理Bar,因此您可以使用内部事件通知Parent。