Question Changing default value of a property of a control (DataGridView).

priyamtheone

Well-known member
Joined
Sep 20, 2007
Messages
94
Programming Experience
Beginner
I am inheriting my own datagridview (say MyDataGridView) from the standard datagridview control. What I want is that certain properties of MyDataGridView should have a different default value than what its base have. For example, AllowUserToAddRows, AllowUserToDeleteRows, AllowUserToResizeRows properties should have the default values of False; so that when I drag MyDataGridView into a form in the IDE, the default values shown in the properties grid should be False. Later on, if I want to change them to True from the grid, they will be set accordingly. Is it possible somehow?
Please note that I don't want to set the default value of any custom property in MyDataGridView but the properties mentioned above that are derived from the base.
Thanks.
 

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,411
Location
Norway
Programming Experience
10+
You can set those properties in the constructor of your derived class. That will not change the properties default value regarding how designer sees it (DefaultValue attribute), but it will set that as properties initial value when you add a new control to a form. To change the designer default value you have to set DefaultValue attribute, which means you have to override or shadow the base property and apply the attribute.
 

priyamtheone

Well-known member
Joined
Sep 20, 2007
Messages
94
Programming Experience
Beginner
I tried the following way on the Visible property of an inherited label but yet it stays True in the properties grid when compiled and dragged in the IDE. I need to change it manually to take effect.

Code:
Imports System.ComponentModel

Public Class MyLabel
    Inherits Label

    Public Sub New()
        MyBase.New()

        'This call is required by the Component Designer.
        InitializeComponent()
    End Sub

    <DefaultValue(False)> _
    Public Shadows Property Visible As Boolean
        Get
            Return MyBase.Visible
        End Get
        Set(ByVal value As Boolean)
            MyBase.Visible = value
        End Set
    End Property
End Class
Another point is, I also tried the AutoSize property too, with the default value of False. In that case though, in the properties grid, it was showing False but actually the property remains True, as that's what I can see while executing. In order to set the value to False, I need to set it to True and then back to False again. :confusion:
 

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,411
Location
Norway
Programming Experience
10+
Remember that the base class will return its initial value no matter what you do, therefore you must as I said set a new initial value in your derived class, which is best done in your constructor.

The DefaultValue attribute is controlling what value the designer will see as default, and the standard behaviour is that designer will serialize only a non-default value in form generated code. In Properties window a property with non-default value appears bolded and you can doubleclick it or use context menu Reset to have it set the default value.

Think about the AllowUserToAddRows property for standard DataGridView control for example, DataGridView class sets this to True when it is created, its attribute says that is the default value and designer will not generate a '.AllowUserToAddRows=True' form code line. If you change the value to False designer sees this as a non-default value and adds a code line to form '.AllowUserToAddRows=False'.

Then you inherit that class, Shadows and set new designer default value for the property, but fail to set the initial value (like your previous post). When an instance of your class is created it first creates an instance of the base class (MyBase.New), where AllowUserToAddRows=True, designer sees this as a non-default value and generates form code 'AllowUserToAddRows=True'. If you reset the property or change it to False designer now considers the value default and remove the code '.AllowUserToAddRows=True'. Now there is no code that set that property to False and whenever a new instance is created base class returns True. Designer again add the form code for non-default value '.AllowUserToAddRows=True'. This is what happens each time you compile.

So, inherit the class, Shadows and set new designer default value and initial value for the property. What happens is same as explained above, but now your class sets the value to False also. Designer sees the default value and does not generate code to set property value. Since your class sets the value to False after base is created this is the value returned for new instances. If you change the value to True designer will generate a form code line '.AllowUserToAddRows=True' which is set after inherited class is created and thus is persisted also.
 

priyamtheone

Well-known member
Joined
Sep 20, 2007
Messages
94
Programming Experience
Beginner
Please check if I did it right.

Code:
Imports System.ComponentModel

Public Class MyDataGridView
    Inherits DataGridView

    Public Sub New()
        MyBase.New()

        'This call is required by the Component Designer.
        InitializeComponent()
        Me.AllowUserToAddRows = False
    End Sub

    <DefaultValue(False)> _
    Protected Shadows Property AllowUserToAddRows()
        Get
            Return MyBase.AllowUserToAddRows
        End Get
        Set(ByVal value)
            MyBase.AllowUserToAddRows = value
        End Set
    End Property
End Class
The result is, everything goes fine as long as AllowUserToAddRows is False. When I set it to True and execute the application, it is set back to False again; i.e. if I want AllowUserToAddRows to have a different value other than its default one at a later time after design, that's not going to happen. Another point to note is, even when AllowUserToAddRows is kept to its default value (False), it appears bolded.

Also tried the following way but of same effect.

Code:
Imports System.ComponentModel

Public Class MyDataGridView
    Inherits DataGridView

    Private _AllowUserToAddRows As Boolean

    Public Sub New()
        MyBase.New()

        'This call is required by the Component Designer.
        InitializeComponent()
        Me.AllowUserToAddRows = False
    End Sub

    <DefaultValue(False)> _
    Protected Shadows Property AllowUserToAddRows()
        Get
            Return _AllowUserToAddRows
        End Get
        Set(ByVal value)
            _AllowUserToAddRows = value
            MyBase.AllowUserToAddRows = value
        End Set
    End Property
End Class
 

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,411
Location
Norway
Programming Experience
10+
First is nearly correct, but you have the signature and access level wrong, change to this:
Public Shadows Property AllowUserToAddRows() As Boolean
 

priyamtheone

Well-known member
Joined
Sep 20, 2007
Messages
94
Programming Experience
Beginner
Ah! My bad. That's a slip-up. Yes, now it's working perfectly. Thanks @JohnH for making things clear to me. Your 2nd post was really very helpful. It aided me to know how the system treats a property internally in respect to the default value. However, I would like to get your help on how a custom label can be created that shall have the AutoSize property with default value as well as the initial value as False. I wrote the code but every time the control is dragged into the IDE, the property in the grid shows True. Is it because of the fact that the standard label control has the default value of AutoSize as False and the initial value as True. So, when I inherit mine, the system finds that the parent default value, inherited default value and inherited initial value are all same (False) and doesn't serialize it. Later, as it finds the initial value of the parent different (True), it adds the code to the form?

My code follows:

Code:
Imports System.ComponentModel

Public Class MyLabel
    Inherits Label

    <System.Diagnostics.DebuggerNonUserCode()> _
    Public Sub New()
        MyBase.New()

        'This call is required by the Component Designer.
        InitializeComponent()
        Me.AutoSize = False
    End Sub

    <DefaultValue(False)> _
    Public Shadows Property AutoSize As Boolean
        Get
            Return MyBase.AutoSize
        End Get
        Set(ByVal value As Boolean)
            MyBase.AutoSize = value
        End Set
    End Property
End Class
 

JohnH

VB.NET Forum Moderator
Staff member
Joined
Dec 17, 2005
Messages
15,411
Location
Norway
Programming Experience
10+
The label class has a ToolboxItem attribute applied of type AutoSizeToolboxItem, which sets AutoSize to True after control is added from Toolbox. This is also the reason AutoSize value is bolded, because default value is False. If you create a Label in code AutoSize will return False. To remedy all you have to do is set the default ToolboxItem attribute:
<ToolboxItem(True)> _
Public Class MyLabel
    Inherits Label     
End Class
 
Top Bottom