Search code examples
vb.netwinformsiextenderprovider

VB.Net Extending Object IExtenderProvider


Ok, I have been fighting this for a couple of days and I am at my wits end... I am trying to add a browsable property that is visible in the PropertyGrid during runtime by extending the Controls. No matter what I do, the iExtenderProvider doesn't appear to actually run.

The iExtenderProvider is located in a second project, and a reference was added to the main project. (code Below)

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

I then build the second project, go back to the first project, and nothing in my properties window, I instantiate a control in the code and then try to find my "Count" property and there is nothing there. Any suggestions as to what could be the problem?


Solution

  • Before reading the answer

    Make sure you know:

    An extender provider is a component that provides properties to other components. The property provided by the extender provider actually resides in the extender provider object itself and therefore is not a true property of the component it modifies.

    At design time, the property appears in property window.

    At run time, however, you cannot access the property through the component itself. Instead, you can call the getter and setter methods on the extender component.

    To implement an extender provider

    • Inherit from Component and implement the IExtenderProvider interface.
    • Decorate your component class with ProvideProperty attribute and introduce provided property and the target control type.
    • When implementing the CanExtend method, return true for each control type that you want to provide property for.
    • Implement getter and setter methods for the provided properties.

    Learn More

    Example

    Using the below code you can implement an extender component ControlExtender. When you build the code and put an instance of ControlExtender on your the form, it extends all controls and add SomeProperty on ControlExtender1 property for your controls in property grid.

    1. Add a Component to the project and name it ControlExtender
    2. Then use these codes in 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
    

    Note: You can also inherit Control based on your requirements. But in most cases inheriting a Component makes more sense.