问题
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*
回答1:
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);
}
回答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.
回答3:
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.
来源:https://stackoverflow.com/questions/21284381/using-a-combobox-usercontrol-and-some-forms-to-change-language-for-entire-proj