Search code examples
c#vb.netwinformsvisual-studiodesigner

Property value of base class not saved by designer


I have added a form to my WinForms project in Visual Studio Express 2013 that I want to use as a base form for other forms. Say I put a button on this form and I want to have a property that makes this button visible or invisible.

Imports System.ComponentModel
Public Class MyForm
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
    Public Property ButtonVisible As Boolean
        Get
            Return Button1.Visible
        End Get
        Set(value As Boolean)
            Button1.Visible = value
        End Set
    End Property
End Class

The designer for this file was not changed. I just added a button to a new form.

When I now create a new form that inherits this class I can change the value of this property and at design time the button indeed becomes visible or invisible. However when I compile the project the property is resetted back to the default value. When I examine the designer file of the derived form I see, that the changed property value is not added to it and therefore vanishes into thin air. When I add ButtonVisible = False manually to the designer file it works and stays there, so I guess the problem lies in the fact, that the Designer does not add the line to the designer file.

This is the designer file of the derived form, after I changed the property value in the designer:

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form2
    Inherits MyForm

    'Das Formular überschreibt den Löschvorgang, um die Komponentenliste zu bereinigen.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Wird vom Windows Form-Designer benötigt.
    Private components As System.ComponentModel.IContainer

    'Hinweis: Die folgende Prozedur ist für den Windows Form-Designer erforderlich.
    'Das Bearbeiten ist mit dem Windows Form-Designer möglich.  
    'Das Bearbeiten mit dem Code-Editor ist nicht möglich.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Me.SuspendLayout()
        '
        'Form2
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(284, 261)
        Me.Name = "Form2"
        Me.Text = "Form2"
        Me.ResumeLayout(False)

    End Sub
End Class

As you can see in the code at the top, I already tried to solve the problem by testing the different values for DesignerSerializationVisible, but they seem to have no effect.

Is there anything I overlooked? How should I add properties that change controls in the underlying base class?
Both C# or VB.NET answers are very much appreciated, whatever you like best.


Solution

  • First, it seems you misunderstood the DesignerSerializationVisibility.Content value of DesignerSerializationVisibility attribute.

    You need to use the DesignerSerializationVisibility.Visible value to save the value of a property. See this related tread: Properties won't get serialized into the .designer.cs file

    Then you can't refer directly to the Button.Visible property in your custom property. The visibility state of the button will be reset to its default value (True) each time you open the inherited form. So your custom property will always show True when the form will be loaded.

    You need to

    • store the state in a variable
    • adjust the button visibility after InitializeComponent method and when the value of your property changes.

    Public Class MyForm
    
        Public Sub New()
            InitializeComponent()
             Me.Button1.Visible = _buttonVisibility
        End Sub
    
        Private _buttonVisibility As Boolean = True
    
        <DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)>
        Public Property ButtonVisible As Boolean
            Get
                Return _buttonVisibility
            End Get
            Set(value As Boolean)
                _buttonVisibility = value
                Button1.Visible = value
            End Set
        End Property
    
    End Class