Question wrap object issue during runtime

Eric101

New member
Joined
Dec 11, 2008
Messages
4
Programming Experience
Beginner
Hi,

I need to wrap a class and change its attributes to readonly during
run-time. My class has primitive datatype properties and a lot of properties
with class datatype. I have a code sampe that wrap "partially" of the class properties. So far, all of the datatypes could be wrap except for properties with class datatype.


Here's sample of my code. Remember to add System.Design reference into your project

VB.NET:
Imports System.Reflection
Imports System.ComponentModel
Imports System.Windows.Forms.Design

Public Class MyForm
    Private item As ClassToWrap
    Private cloneVersion As ReadOnlyTypeDescriptor

    Private Sub Form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        item = New ClassToWrap
        item.A = 8
        item.B = 12
        item.MyOtherClass = New AnotherClass
        item.MyOtherClass.Name = "My name"
        cloneVersion = New ReadOnlyTypeDescriptor(item)

        PropertyGrid1.Enabled = True
        PropertyGrid1.SelectedObject = item
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        PropertyGrid1.SelectedObject = cloneVersion
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        PropertyGrid1.SelectedObject = item
    End Sub

End Class

Public Class ClassToWrap
    Private itemA As Integer
    Private itemB As Integer
    Private itemString As String
    Private editor As String
    Private comp As Object

    Public Property A() As Integer
        Get
            Return itemA
        End Get

        Set(ByVal value As Integer)
            itemA = value
        End Set
    End Property

    Public Property B() As Integer
        Get
            Return itemB
        End Get

        Set(ByVal value As Integer)
            itemB = value
        End Set
    End Property

    Public Property Name() As Integer
        Get
            Return itemString
        End Get

        Set(ByVal value As Integer)
            itemString = value
        End Set
    End Property

    <Editor(GetType(MyCustomEditor), GetType(Drawing.Design.UITypeEditor))> _
    Public Property MainEditor() As String
        Get
            Return editor
        End Get
        Set(ByVal value As String)
            editor = value
        End Set
    End Property

    Private _myOtherClass As AnotherClass
    Public Property MyOtherClass() As AnotherClass
        Get
            Return _myOtherClass
        End Get
        Set(ByVal value As AnotherClass)
            _myOtherClass = value
        End Set
    End Property

    Private _path As String
    <EditorAttribute(GetType(System.Windows.Forms.Design.FolderNameEditor), GetType(System.Drawing.Design.UITypeEditor))> _
    Public Property FolderPath() As String
        Get
            Return _path
        End Get
        Set(ByVal value As String)
            _path = value
        End Set
    End Property
End Class

<TypeConverter(GetType(ExpandableObjectConverter))> _
Public Class AnotherClass
    Private _name As String
    Private _editor As String
    Private _anotherPath As String

    Public Property Name() As String
        Get
            Return _name
        End Get
        Set(ByVal value As String)
            _name = value
        End Set
    End Property

    <EditorAttribute(GetType(System.Windows.Forms.Design.FolderNameEditor), GetType(System.Drawing.Design.UITypeEditor))> _
    Public Property AnotherFolderPath() As String
        Get
            Return _anotherPath
        End Get
        Set(ByVal value As String)
            _anotherPath = value
        End Set
    End Property

    <Editor(GetType(MyCustomEditor), GetType(Drawing.Design.UITypeEditor))> _
    Public Property MyEditor() As String
        Get
            Return _editor
        End Get
        Set(ByVal value As String)
            _editor = value
        End Set
    End Property
End Class

Public Class MyCustomEditor
    Inherits System.Drawing.Design.UITypeEditor

    Public Overrides Function GetEditStyle(ByVal context As System.ComponentModel.ITypeDescriptorContext) As System.Drawing.Design.UITypeEditorEditStyle
        Return Drawing.Design.UITypeEditorEditStyle.Modal
    End Function

    Public Overrides Function EditValue(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal provider As System.IServiceProvider, ByVal value As Object) As Object
        Dim editor As New Form
        editor.StartPosition = FormStartPosition.CenterParent
        editor.Text = "This is my editor"
        editor.Show()
        Return "Editor activated"
    End Function
End Class

And this is the class that wrap the object:
VB.NET:
Option Strict On

Imports System.Reflection
Imports System.ComponentModel

Class ReadOnlyTypeDescriptor
    Inherits CustomTypeDescriptor
    Private mComponent As Object

    Public Sub New(ByVal component As Object)
        MyBase.New(TypeDescriptor.GetProvider(component).GetTypeDescriptor(component))
        mComponent = component
    End Sub

    Public Overloads Overrides Function GetProperties(ByVal attributes As Attribute()) As PropertyDescriptorCollection

        Dim inPdc As PropertyDescriptorCollection = MyBase.GetProperties(attributes)

        Dim pdcs As PropertyDescriptor() = New PropertyDescriptor(inPdc.Count - 1) {}
        For i As Integer = 0 To pdcs.Length - 1
            If inPdc(i).IsBrowsable Then
                If inPdc(i).IsReadOnly Then
                    pdcs(i) = inPdc(i)
                Else
                    pdcs(i) = New ReadOnlyPropertyDescriptor(inPdc(i))
                End If
            End If
        Next

        Return New PropertyDescriptorCollection(pdcs, True)
    End Function

    Public Overrides Function GetProperties() As System.ComponentModel.PropertyDescriptorCollection
        Return MyBase.GetProperties()
    End Function

    Private Class ReadOnlyPropertyDescriptor
        Inherits PropertyDescriptor

        Private mParent As PropertyDescriptor

        Public Sub New(ByVal parent As PropertyDescriptor)
            MyBase.New(parent, New Attribute() {ReadOnlyAttribute.Yes})
            mParent = parent
        End Sub

        Public Overloads Overrides Function CanResetValue(ByVal component As Object) As Boolean
            Return False
            ' Read Only 
        End Function

        Public Overloads Overrides ReadOnly Property ComponentType() As Type
            Get
                Return mParent.ComponentType
            End Get
        End Property

        Public Overloads Overrides Function GetValue(ByVal component As Object) As Object
            Return mParent.GetValue(component)
        End Function

        Public Overloads Overrides ReadOnly Property IsReadOnly() As Boolean
            Get
                Return True
            End Get
        End Property

        Public Overloads Overrides ReadOnly Property PropertyType() As Type
            Get
                Return mParent.PropertyType
            End Get
        End Property

        Public Overloads Overrides Sub ResetValue(ByVal component As Object)

            ' Read Only 
        End Sub

        Public Overloads Overrides Sub SetValue(ByVal component As Object, ByVal value As Object)
            mParent.SetValue(component, value)
        End Sub

        Public Overloads Overrides Function ShouldSerializeValue(ByVal component As Object) As Boolean
            Return mParent.ShouldSerializeValue(component)
        End Function
    End Class

End Class
 
Try to use the ReadOnlyObject class posted here Readonly PropertyGrid instead of your ReadOnlyTypeDescriptor class.
 
I tried this code before. The problem with ReadOnlyObject from the forum is that I lose all expandable facilities of property of class datatype. If you try it with my code you'll see the property of class property is not displayed.
 
Back
Top