3kings 3kings - 4 months ago 20
Vb.net Question

How to add a Property To a System Defined Class VB.NET

Lets just say i want to add a property to a class such as

DataGridViewColumn
.

Is there such a way to do this that i can cast these objects to lets say
DataGridViewCheckBoxColumn
This is currently what i am doing but is giving me an error.

I have my own class
DataGridViewColumn


Public Class DataGridViewColumn
Inherits System.Windows.Forms.DataGridViewColumn

Private Field As String
Public Property SomeField() As String
Get
Return Field
End Get
Set(ByVal value As String)
Field = value
End Set
End Property
End Class


Which is fine and works how i want it to. But when i go try something like this... It does not like it

Private Function gen(name As String) As DataGridViewColumn
Select Case name
Case "DataGridViewTextBoxColumn"
Dim c2 As New DataGridViewTextBoxColumn
c2.Name = "tstColumn"
c2.HeaderText = "Test Column"
c2.ReadOnly = False
Return c2
End Select
Return Nothing
End Function


Is there any way to allow me to do this? I have also tried making a
DataGridViewTextBoxColumn
Class and inherting the
System.Windows.Forms.DataGridViewTextBoxColumn
but nothing seems to work.

Error simply says Cannot be converted to type DataGridViewColumn even when i have my own DataGridViewTextBoxColumn

Answer

I figured that I'd provide the answer I suggested in my comment regardless. If you only want a single "property" then you could do this:

Imports System.Runtime.CompilerServices

Namespace YourBusinessName.Windows.Forms

    Public Module DataGridViewColumnExtensions

        <Extension>
        Public Function GetField(source As DataGridViewColumn) As String
            Return TryCast(source.Tag, String)
        End Function

        <Extension>
        Public Sub SetField(source As DataGridViewColumn, value As String)
            source.Tag = value
        End Sub

    End Module

End Namespace

You can then use those method like this:

Imports YourBusinessName.Windows.Forms

'...

Me.Column1.SetField("Hello World")

Dim fieldValue = Me.Column1.GetField()

If you wanted multiple "properties" then you could beef that up with a Dictionary:

Imports System.Runtime.CompilerServices

Namespace YourBusinessName.Windows.Forms

    Public Module DataGridViewColumnExtensions

        <Extension>
        Public Function GetField1(source As DataGridViewColumn) As String
            Return GetField(source, "Field1")
        End Function

        <Extension>
        Public Function GetField2(source As DataGridViewColumn) As String
            Return GetField(source, "Field2")
        End Function

        Private Function GetField(source As DataGridViewColumn, propertyName As String) As String
            Dim fields = TryCast(source.Tag, Dictionary(Of String, Object))

            If fields Is Nothing OrElse Not fields.ContainsKey(propertyName) Then
                Return Nothing
            End If

            Return TryCast(fields(propertyName), String)
        End Function

        <Extension>
        Public Sub SetField1(source As DataGridViewColumn, value As String)
            SetField(source, "Field1", value)
        End Sub

        <Extension>
        Public Sub SetField2(source As DataGridViewColumn, value As String)
            SetField(source, "Field2", value)
        End Sub

        Private Sub SetField(source As DataGridViewColumn, propertyName As String, value As String)
            Dim fields = TryCast(source.Tag, Dictionary(Of String, Object))

            If fields Is Nothing Then
                fields = New Dictionary(Of String, Object)
                source.Tag = fields
            End If

            fields(propertyName) = value
        End Sub

    End Module

End Namespace

You would still use those methods in the same way:

Imports YourBusinessName.Windows.Forms

'...

Me.Column1.SetField1("Hello World")

Dim fieldValue = Me.Column1.GetField2()

Note that methods that extend the DataGridViewColumn class can be called on an object of any type that is or inherits from DataGridViewColumn.