VB.Net 扩展对象 IExtenderProvider

Posted

技术标签:

【中文标题】VB.Net 扩展对象 IExtenderProvider【英文标题】:VB.Net Extending Object IExtenderProvider 【发布时间】:2016-01-15 00:39:19 【问题描述】:

好的,我已经为此奋斗了几天,但我束手无策...我正在尝试通过扩展控件来添加一个在运行时在 PropertyGrid 中可见的可浏览属性。无论我做什么,iExtenderProvider 似乎都没有实际运行。

iExtenderProvider 位于第二个项目中,并在主项目中添加了一个引用。 (代码如下)

Imports System.ComponentModel
Imports System.Windows.Forms

Public Class ControlArray
             Inherits Component
             Implements IExtenderProvider
    <Browsable(True)> Public ReadOnly Property Count As Integer
        Get
            Return 0
        End Get
    End Property

    Public Function CanExtend(ByVal extendee As Object) As Boolean Implements IExtenderProvider.CanExtend
       Return TypeOf extendee Is Control
    End Function
End Class

然后我构建第二个项目,返回第一个项目,我的属性窗口中没有任何内容,我在代码中实例化一个控件,然后尝试找到我的“计数”属性,但那里没有任何内容。关于可能是什么问题的任何建议?

【问题讨论】:

这并不是实现IExtenderProvider 的正确方法——缺少一些东西。 IExtenderProvider 与 VS IDE 配合得很好,但它不适用于 PropertyGrid,因为它使用反射来获取属性 - 你需要一个 TypeConverter 为了澄清,ExtenderProvider 用于在设计时在 VS 中添加属性。它们不是真正的属性(请参阅添加工具提示文本的语法)。对于运行时,您需要一个 TypeConverter 和一个自定义 PropertyDescriptor。这些是很多样板代码,对于 RO 属性来说似乎需要做很多工作。 只是一个起点......最终结果将是集成,以便能够将伪名称访问到 PropertyGrid 中,以便用户可以在期间“更改控件名称”运行时。 【参考方案1】:

阅读答案之前

确保你知道:

扩展器提供程序是一个向其他组件提供属性的组件。扩展器提供者提供的属性实际上驻留在扩展器提供者对象本身中,因此不是它所修改的组件的真实属性。

在设计时,属性出现在属性窗口中。

在运行时,您不能通过组件本身访问该属性。相反,您可以在扩展器组件上调用 getter 和 setter 方法。

实现扩展提供程序

Component 继承并实现IExtenderProvider 接口。 用ProvideProperty 属性装饰你的组件类,并引入提供的属性和目标控件类型。 在实现 CanExtend 方法时,为您要为其提供属性的每个控件类型返回 true。 为提供的属性实现 getter 和 setter 方法。

了解详情

Extender Provider Overview IExtenderProvider How to: Implement a HelpLabel Extender Provider

示例

使用以下代码,您可以实现扩展器组件ControlExtender。当您构建代码并将ControlExtender 的实例放在表单上时,它会扩展所有控件并在属性网格中为您的控件添加SomeProperty on ControlExtender1 属性。

    在项目中添加Component并将其命名为ControlExtender 然后在ControlExtender.vb 中使用这些代码
Imports System.ComponentModel
Imports System.Windows.Forms

<ProvideProperty("SomeProperty", GetType(Control))>
Public Class ControlExtender
    Inherits Component
    Implements IExtenderProvider
    Private controls As New Hashtable
    Public Function CanExtend(extendee As Object) As Boolean Implements IExtenderProvider.CanExtend
            Return TypeOf extendee Is Control
    End Function

    Public Function GetSomeProperty(control As Control) As String
        If controls.ContainsKey(control) Then
            Return DirectCast(controls(control), String)
        End If

        Return Nothing
    End Function
    Public Sub SetSomeProperty(control As Control, value As String)
        If (String.IsNullOrEmpty(value)) Then
            controls.Remove(control)
        Else
            controls(control) = value
        End If
    End Sub
End Class

注意:您也可以根据您的要求继承Control。但在大多数情况下,继承 Component 更有意义。

【讨论】:

我至少提到您也可以继承,因为这就是所有 MSDN 示例的方式(尽管从控件继承似乎很奇怪), 谢谢。嗯,似乎我将不得不弄清楚如何将新属性添加到任何控件。谢谢。 不客气。有许多解决方案可以满足这种一般要求。真正的需求是什么? 尝试为我正在处理的应用程序生成 Visual Studio。就目前而言,我可以添加任何控件,然后 PropertyGrid 将显示除 Name 属性之外的所有属性,并且也不会显示任何事件。 @IvanFerrerVilla 是的,很好!我可以确认;但是我可能永远不会把它写成 getSomething/setSomething,即使在 C# 中也是如此。

以上是关于VB.Net 扩展对象 IExtenderProvider的主要内容,如果未能解决你的问题,请参考以下文章

为什么像Java,C#和VB.NET现代面向对象的语言不支持多重继承[复制]

C# 到 VB.Net:为啥转换为 VB 时编译失败?

将 vb.net 类对象转换为 vb.net 中的 JSON 字符串

VB .NET 制作的DLL无法被 .NET 程序引用

VB.NET和C++之间的区别

使用 NamePipe [进程间通信] VB.NET 传输对象