2016-01-15 54 views
2

好吧,我一直在争取这几天,我在我的智慧结束......我试图添加一个可浏览的属性,在PropertyGrid中可见的运行时通过扩展控制。无论我做什么,iExtenderProvider都不会真正运行。VB.Net扩展对象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 

我再建第二个项目,再回到第一个项目,并没有在我的属性窗口,我在代码中实例化一个控件,然后试图找到我的“伯爵”财产那里什么也没有。有什么建议可能是什么问题?

+0

这不完全是实现'IExtenderProvider'的正确方式 - 缺少一些东西。 'IExtenderProvider'与VS IDE协同工作,但不会与PropertyGrid一起使用,因为它使用反射来获取属性 - 您需要一个TypeConverter – Plutonix

+0

为了阐明,ExtenderProvider用于在设计时在VS中添加属性。它们不是真正的属性(请参阅添加工具提示文本的语法)。对于运行时你需要一个'TypeConverter'和一个自定义的'PropertyDescriptor'。这些是很多样板代码,对于RO属性看起来像很多工作。 – Plutonix

+0

只是一个起点......最终的结果是在集成中能够在PropertyGrid中访问一个伪名,以便用户可以在运行时“更改控制名”。 –

回答

1

之前阅读答案

确保你知道:

的扩张提供者是提供性能,其他组件的组件。由扩展提供程序提供的属性实际上驻留在扩展提供程序提供程序对象本身中,因此不是其修改的组件的真实属性。

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

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

要实现扩展程序提供Component

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

了解更多

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

  1. 添加Component到项目并将其命名为ControlExtender
  2. ControlExtender.vb
Imports System.ComponentModel 
Imports System.Windows.Forms 

<ProvideProperty("SomeProperty", GetType(Control))> 
Public Class ControlExtender 
    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更有意义。

+0

我会至少*提及*,你也可以继承,因为这是如何所有的MSDN示例(虽然继承自控制似乎很奇怪), – Plutonix

+1

@Plutonix添加到答复。希望答案对未来的读者有用。这是一个建设性的讨论。很高兴与你讨论。 –

+0

谢谢。嗯,似乎我将不得不弄清楚如何将新属性添加到任何控件。谢谢。 –