Over a long period, some users have reported problems with code generated in the function InitializeComponent(), looking something like this:
this.labelX9.BackgroundStyle.Class = global::YourProject.MultiLang._668;
The reference to MultiLang obviously implicates the Multi-Language Add-In, but the code in InitializeComponent() is neither generated nor modified by the Add-In. This effect has always baffled me.
Now I think I know what is happening, and I can illustrate it with a sample program. This sample contains several parts, which I will try to describe in detail
This sample defines
I have made the sample in VB, but it could just as easily be in C#. I am sure that there is no difference.
Imports System.ComponentModel
<TypeConverterAttribute(GetType(ExpandableObjectConverter))> _
Public Class MyObject
Private mEmpty As String = ""
Public Property Empty as String
Get
Return mEmpty
End Get
Set(ByVal value As String)
mEmpty = value
End Set
End Property
End Class
This class contains a single String property, which is initialized with an empty string.
This property can have the <Localizable(True)> attribute, but this is not necessary.
This is the user defined code in the UserControl. Obviously there is more code in the .designer.vb file, but that does not interest us.
Imports System.ComponentModel
Public Class ControlWithObject
Private mObject As New MyObject
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
Public ReadOnly Property ChildObject as MyObject
Get
Return mObject
End Get
End Property
End Class
This UserControl has a single property named ChildObject, of type MyObject.
I have placed a single instance of the UserControl ControlWithObject on the form.
As you can see, the ChildObject property can be expanded in the properties window.
This form contains no user defined code.
I have a single resource strings to the project, named EmptyString and containing an empty string.
Before going any further, I want to take a look at some of the code in InitializeComponent(), in the .designer.vb file.
' 'ControlWithObject1 ' Me.ControlWithObject1.BackColor = System.Drawing.Color.DarkRed Me.ControlWithObject1.ChildObject.Empty = "" Me.ControlWithObject1.Location = New System.Drawing.Point(12, 12) Me.ControlWithObject1.Name = "ControlWithObject1" Me.ControlWithObject1.Size = New System.Drawing.Size(150, 150) Me.ControlWithObject1.TabIndex = 0
Now lets look at what happens when we set the Localizable property of the form to True.
As you probably know, this modifies the code generated in InitializeComponent. Lets take a look at the now code.
' 'ControlWithObject1 ' Me.ControlWithObject1.BackColor = System.Drawing.Color.DarkRed Me.ControlWithObject1.ChildObject.Empty = Global.EmptyStringTest2.My.Resources.Resources.EmptyString resources.ApplyResources(Me.ControlWithObject1, "ControlWithObject1") Me.ControlWithObject1.Name = "ControlWithObject1"
As we would expect, a call to resources.ApplyResources() has been added, which loads the localizable properties from a resource file. The actual values of these properties have been moved into the resource file Form1.resx.
However, this does not apply to the properties of ChildObject.
Here something rather strange has happened. The property ChildObject.Empty, which contains an empty string, is now loaded from the resource string EmptyString.
This is strange for two reasons:
The effect is, that the forms designer decides to load a property from a resource string, for no apparent reason.
So far as I can tell:
If:
then the forms designer may decide to load that string property from the empty resource string in MultiLang.resx.
This effect may lead to a compilation error. In fact, you will probably only notice it if it does cause a compilation error.