3
votes

I'm working on a project that involves localizing a large number of Windows Forms.

We're dealing with layout using the TableLayoutPanel control, which works nicely.

One area we're striking problems with is when we set the Form.Localizable property to True, we then end up having to manage one .resx file per form per language. That'd be fine if the .resx files only contained the Localized text, but it also contains a vast amount of layout data for the form.

Is there a way to separate the localizable text elements from the control layout information, that continues to work in the visual studio IDE?

I've noticed that I can modify my the form's designer file to look at another resource file, but when I use the form designer, these changes are deleted:

'
'Label1
'
Me.Label1.AutoSize = True
Me.Label1.Dock = System.Windows.Forms.DockStyle.Top
Me.Label1.Location = New System.Drawing.Point(3, 0)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(61, 13)
Me.Label1.TabIndex = 1
Me.Label1.Text = My.Resources.ResourceManager.GetString("Form1_Label1_Text")
2
Okay, I never did really find a completely satisfactory answer to this question. But I came up with a solution that offended me the least, which I'll detail below.Derek Tomes

2 Answers

2
votes

I never found an answer to this I was completely happy with. But this is the solution I ended up implementing:

  1. I ended up setting Form.Localizable = false because I didn't want to maintain all those identical .resx files

  2. All the UI elements get a de-facto value (like "O_K_") that is visibly not localized.

  3. I treated the form / controls exactly the same as all my other localizable content (error messages, log messages etc.) and just gave them unique keys like "cmdOkTextOK" so they could be shared across multiple forms

  4. I created LocalizeComponent() functions on every form and called it from the constructor immediately after the InitializeComponent() function, as follows:

Public Class Form1
    Public Sub New()
        ' This call is required by the Windows Form Designer.
        InitializeComponent()
        ' Add any initialization after the InitializeComponent() call.
        LocalizeComponent()
    End Sub

    Private Sub LocalizeComponent()
        ' Localizes all the ui elements from a common Resource
        Me.SuspendLayout()
        Me.cmdOK.Text = My.Resources.ResourceManager.GetString("cmdOKTextOK")
        Me.cmdCancel.Text = My.Resources.ResourceManager.GetString("cmdCancelTextCancel")
        Me.cmdApply.Text = My.Resources.ResourceManager.GetString("cmdApplyTextApply")
        Me.ResumeLayout(False)
    End Sub
End Class

This moves the localization of visible control elements out of the designer file (where it was destroyed each time I did a form edit) and puts it back under my control.

I'm still not 100% happy, because the controls are being created with non-localized strings at run time that are latter being updated. But it will save me from a maintenance nightmare I really don't want!

THANKS to everyone who took the trouble to answer. I appreciate it! I'm not sure what you're meant to do when answering your own question to mark it 'answered' so if someone could point me at that without burning me too bad that'd be appreciated.

0
votes

You can have files as resources, so that's something you should be able to accomplish since it's not changed during the run-time, only accessed from what you've said. Maybe an xml file with language entries and the translated text, for example. <entry key = "btnOK">Ok</entry>. At run-time you can make the decision what language node to load in

<Languages>
    <Language name="Spanish">
         <Entry key="Yes">Si</Entry>

The last place I worked, we used xml files, one for each language, that we bundled with the install. When the solution was loaded in, we loaded the desired file into a global HashTable and set each bit of text that way. There may be a more optimal solution, but maybe something along these lines may help you. hashTable("successfulSaveMsg") would return "You have successfully saved your widget", for example.