0

I have a Windows Forms application project, and on the main form I have a menu strip. Some place in this menu strip it is possible to select various languages. For example if the user selects "English", everything on this main form (and others in the future) should be turned into English language.

I took this tutorial: click

This works fine with labels and such, but it does not work at all with the tool strip menu items. They just stay with their default text.

I tried to add two more lines to the ChangeLanguage method:

private void ChangeLanguage(string lang)
{
    foreach (Control c in this.Controls)
    {
        ComponentResourceManager resources = new ComponentResourceManager(typeof(Form1));
        resources.ApplyResources(c, c.Name, new CultureInfo(lang));
        ComponentResourceManager res2 = new ComponentResourceManager(typeof(ToolStripMenuItem));
        res2.ApplyResources(c, c.Name, new CultureInfo(lang));
    }
}

But it fails and says:

Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "System.Windows.Forms.ToolStripMenuItem.resources" was correctly embedded or linked into assembly "System.Windows.Forms" at compile time, or that all the satellite assemblies required are loadable and fully signed.

Not sure how to proceed - any help appreciated.

gosr
  • 4,593
  • 9
  • 46
  • 82

1 Answers1

2

You have to remove the last 2 lines in your foreach loop. That lines say that you are looking for the localization information in System.Windows.Forms.ToolStripMenuItem.resx file, but you want to look in your Forms resources file.

ToolstripMenuItems are added to an ToolStripItems DropDownItems Collection and not to the Controls collection of your Form. This might help you solving your problem.

private void ChangeLanguage(string lang) {
    ComponentResourceManager resources = new ComponentResourceManager(typeof(Form1));
    foreach (Control c in this.Controls) {
        resources.ApplyResources(c, c.Name, new CultureInfo(lang));
    }

    foreach (ToolStripItem item in toolStrip1.Items) {
        if (item is ToolStripDropDownItem)
            foreach (ToolStripItem dropDownItem in ((ToolStripDropDownItem)item).DropDownItems) {
                resources.ApplyResources(dropDownItem, dropDownItem.Name, new CultureInfo(lang));
            }
    }
}

If you have further drop down items you should consider a recursive approach.

Edit: To my first comment

private void ChangeLanguage(string lang) {
    ComponentResourceManager resources = new ComponentResourceManager(typeof(Form1));
    foreach (Control c in this.Controls) {
        resources.ApplyResources(c, c.Name, new CultureInfo(lang));
    }

ChangeLanguage(toolStrip1.Items); }

private void ChangeLanguage(ToolStripItemCollection collection) {
    foreach (ToolStripItem item in collection) {
        resources.ApplyResources(item, item.Name, new CultureInfo(lang));
        if (item is ToolStripDropDownItem)
            ChangeLanguage(((ToolStripDropDownItem)item).DropDownItems);
    }
}
dwonisch
  • 5,595
  • 2
  • 30
  • 43
  • Thanks, that works some of the way. This only changes the language of the drop down items in the menu strip, not the "headers" of the menu strip or if I have an additional drop down menu inside the first drop down menu. – gosr Oct 05 '11 at 06:53
  • This is what I said would be the [recursive approach](http://www.dotnetperls.com/recursion). Call the method in my edit instead of the second foreach loop. This will now ensure that all layers of your menu structure are looped for localization. – dwonisch Oct 05 '11 at 10:39
  • Thanks. This code works for me. I didn't know the menu items are not from the Form.Controls. – Hao Nguyen Apr 25 '17 at 10:36