Question

Before I begin, I have researched and can't seem to find anything. Note I am very new to UserControl so this might be why it's proven difficult.

I have a combobox in Form1 which when selected allows the user to change between a choice of 21 languages. I have created a UserControl that contains labels, buttons and checkboxes - adds to a form called Print.

If a user selected French, how would I then implement the UserControl to change language for ALL forms in my project?

UserControl:

I have used a get and set method here for a button. When the language is changed in Form1, I want this button (all elements really) to change.

using System.Windows.Forms;

namespace Print
{
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }

        public string LabelPreview
        {
            get
            {
                return Button_Preview.Text;
            }
            set
            {
                Button_Preview.Text = value;
            }
        }
    }
}

Form1:

If string value English is selected in the combobox, call a method - here is where I would like to change language for other forms.

private void ComboBoxLang_SelectedIndexChanged(object sender, EventArgs e)
{
    string selectedItem = this.comboBoxLang.GetItemText(this.comboBoxLang.SelectedItem);

    if (selectedItem == Language.English)
    {
        ToEnglish();
    }
}

private void ToEnglish()
{
    // Cannot actually implement the UserControl, It can't find the method above.
    // When I've tried to implement UserControl in Print, it can't seem to find it either.
    // I've tried:
    // Print.UserControl1.(_LabelPreview doesn't show_);
    // ^ It might be the completely wrong thing to do so excuse me.
}

I'm so confused... Do I program in Print (where the UserControl is added) or/and Form1?! I don't want the design to appear in Form1, but just want to let the other forms know what language has been selected.

Note: I have been using Unicode when translating*

Était-ce utile?

La solution 2

So I've come up with a solution that works for me! I've copied across from the Printer.cs form where I have used a parameter to represent the language chosen, initiated strTextBox to equal label1 and included an if statement to see if the language is English (also working with UserControl to get the value of labels etc.).

Printer

public Printer(string strTextBox)
{
    InitializeComponent();
    label1.Text = strTextBox;

    if (label1.Text == Language.English)
    {
        UserControl111.Label_Option_Multi = "Please select an option:"; //Simple test
    }
}

Form1

private void Print_Click(object sender, EventArgs e)
{
    string selectedItem = this.ComboBox_Lang.GetItemText(this.ComboBox_Lang.SelectedItem);

    Printer p = new Printer(selectedItem);
    p.Show();
}

UserControl

public string Label_Option_Multi
{
    get
    {
        return Label_Option.Text;
    }
    set
    {
        Label_Option.Text = value;
    }
}

As a result, if I select English in Form1.s then open up Printer.cs, the label displays English and translates accordingly.

Autres conseils

How to trigger application-wide language change I described here on your other question Everytime ComboBox is changed (using SelectedIndexChanged) display message in other forms, if opened, of new value

Now, to set controls... One way of doing it is to create Database of phrases with StringId in one table and the StringId, LanguageId, StringValue in another. You would create StringManager object, which will have method GetLanguageSpecificString(stringId, languageId). When language change is triggered, your controls will call GetLanguageSpecificString fro each label you display, etc.

So your data will be like

Table DisplayLanguage
    LanguageId Int
    LanguageName nvarchar
    LanguageCulture varchar

//1, English, us-En
//2, French,  fr-Ca



Table DisplayString
    StringId Int

//1
//2
//3

Table DisplayStringValue
    DisplayStringValueId int
    StringId int
    LanguageId int
    StringValue nvarchar

//1, 1, 1, Person Name
//2, 1, 2, Nome de Persona(or whateever)

Create cache using

"Select * from DisplayStringValue where LanguageId = 1"

And then use Linq or something to select for each control its data from cache because you don't want to hit DB with these for each control

"Select StringValue from DisplayStringValue where StringId = 1 and LanguageId = 1"

Now, combine my other answer with this and you will see that if in your form you have

LanguageChangeObserver.LanguageChanged += MyObserverHandler;

private void MyObserverHandler(languageId)
{
    _formLanguage = languageId;
    // set your controls
    lblFirstName.Text = GetLanguageSpecificString(5, languageId);
    lblLastName.Text = GetLanguageSpecificString(6, languageId);
    // loop through userControls and pass to them language id

}

It would be good idea if your user controls would derive from the single base class that you create and which has already SetNewLanguage Method, so you could do

foreach (var c in form.controls)
{
    MyControlBase currControl = c as MyControlBase;
    if (currControl != null) currControl.SetNewLanguage(languageId);
}

You have to do it same way as for any other control. Imagine you have created your TextBox and now want all your textboxes in the project on each form to do something.

Obviously, you have to get a list of such controls somehow. One approach is to use Application.Forms to iterate through everything. Other is to register your control (add to a list) every time when it's created or shown or what_you_need and de-register (remove from a list) otherwise.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top