首页 > 解决方案 > 动态创建时,UserControl 不能隐藏 Enabled 属性

问题描述

我有一个自定义的用户控件(基本上是一个花哨的按钮),它需要知道何时启用/禁用控件以更改绘图颜色。

我在控件中添加了一个 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 设计器(预编译)创建我的控件时,此方法似乎工作正常。但是,当我在运行时动态创建控件时,GetandSet代码永远不会运行。

有什么想法可能导致这种情况吗?

标签: vb.netwinformsproperties

解决方案


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

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表单的集合访问它。这将返回一个Control引用,因此,如果您要通过它访问该Enabled属性,它将是您调用的基本实现。如果要调用派生实现,则需要将该引用转换为控件的实际类型。这样做的一种选择是使用该OfType方法同时按类型过滤和强制转换,例如

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

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

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

推荐阅读