动态创建时,UserControl 无法隐藏已启用 属性

UserControl can't shadow Enabled property when created dynamically

我有一个自定义 UserControl(基本上是一个花哨的按钮),它需要知道控件何时 enabled/disabled 才能更改绘图颜色。

我在我的控件中添加了一个Shadows 属性如下:

Private _enabled As Boolean

Public Shadows Property Enabled() As Boolean
    Get
        Return Me._enabled
    End Get
    Set(value As Boolean)
        Me._enabled = value

        ' My code here to change the drawing colors

    End Set
End Property

当使用 GUI 设计器(预编译)创建我的控件时,此方法似乎工作正常。但是,当我在运行时动态创建控件时,GetSet 代码永远不会运行。

知道是什么原因造成的吗?

很难确定,因为您没有提供足够的信息,但我怀疑我知道问题出在哪里。当您隐藏一个成员时,您必须通过派生 class 的引用访问该成员,以便调用派生实现。如果您使用基类型的引用,那么它将是您将调用的基实现。这与覆盖成员时不同,在这种情况下,无论引用的类型如何,都将调用派生实现。我通常将其总结为重写遵循对象的类型,而阴影遵循引用的类型。尝试 运行 执行此代码以查看实际效果:

Module Module1

    Sub Main()
        Dim dc As New DerivedClass

        dc.OverrideMethod()
        dc.ShadowMethod()

        Dim bc As BaseClass = dc

        bc.OverrideMethod()
        bc.ShadowMethod()
    End Sub

End Module

Public Class BaseClass

    Public Overridable Sub OverrideMethod()
        Console.WriteLine("BaseClass.OverrideMethod")
    End Sub

    Public Sub ShadowMethod()
        Console.WriteLine("BaseClass.ShadowMethod")
    End Sub

End Class
Public Class DerivedClass
    Inherits BaseClass

    Public Overrides Sub OverrideMethod()
        Console.WriteLine("DerivedClass.OverrideMethod")
    End Sub

    Public Shadows Sub ShadowMethod()
        Console.WriteLine("DerivedClass.ShadowMethod")
    End Sub

End Class

这是输出:

DerivedClass.OverrideMethod
DerivedClass.ShadowMethod
DerivedClass.OverrideMethod
BaseClass.ShadowMethod

如您所见,通过基类型引用调用隐藏方法会调用基实现,而通过基类型引用调用重写方法会调用派生实现。

在您的特定情况下,当您在 运行 时间添加实例时,您没有控件特定类型的字段来访问它,因此您可能通过 Controls 集合访问它的形式。那将是 return 一个 Control 引用,因此,如果您要通过它访问 Enabled 属性,它将是您调用的基本实现。如果你想调用你的派生实现,那么你需要将该引用转换为你的控件的实际类型。这样做的一种选择是使用 OfType 方法按类型过滤并同时进行转换,例如

Dim firstFancyButton = Controls.OfType(Of FancyButton)().First()

否则,执行显式转换,例如

Dim firstFancyButton = DirectCast(Controls("FancyButton1"), FancyButton)