13. diel - Multilingual (Viacjazykové) aplikácie
Vyskúšal som niekoľko spôsobov na preklad aplikácie. Každý z nich má
nejaké výhody a nevýhody. Skúšal som preklad načítaný zo
súboru. Možno ľahko modifikovať a užívateľ si tak môže
nadefinovať ľahko aj vlastný jazyk. Ovšem preklad v aplikácii sa potom
rieši strašne. Potom som skúšal pomocou ***. Resx ** metódou prejdení
všetkých komponentov a nájsť na ich vlastnosti (tooltip, text)
zodpovedajúci preklad. Najviac sa mi však osvedčila metóda, ktorú si teraz
ukážeme a to vytvorenie si onoch * .resx súborov pre jednotlivé jazyky. A
dáta z nich budeme získavať pomocou metóda Translate
, ktorá
vyhľadá zadaný výraz v súbore a vráti jeho preklad. Možno takto skladať
jednoducho vety a na použitie je to veľmi jednoduché. V * .resx súboru je
vlastne XML, kde sú uložený jednotlivé hodnoty.
Do Properties som si pridal zložku Strings
v ktorej som si vytvoril súbor s resources _default.resx
(default
sa volať nemôže, BZE je to kľúčové slovo). Teraz prichádza tá
najhnusnejšia časť. A to prepísať sem všetky stringy. Ovšem možno si to
zjednodušiť. Prejsť všetky komponenty
foreach (Control c in Controls)
a ak je to potrebné
Label
c is Label
(niektoré komponenty nemajú
vlastnosť text) a jeho Text
má nejakú hodnotu
!String.IsNullOrEmpty(c.Text)
tak si ju uložím do súboru. Keď
si otvoríte onen súbor _default.resx
a zídete dolu uvidíte ako
sa to tam generuje:
<data name="hello" xml:space="preserve"> <value>Ahoj</value> </data>
Takže môžete urobiť toto:
foreach (Control c in Controls) { if ((c is Label) && (!String.IsNullOrEmpty(c.text))) { sw.WriteLine("<data name=\"" + c.Name + "\" xml:space=\"preserve\">\r\n" + "<value>" + c.Text + "</value>\r\n" + "</data>" ); } }
Potom to len pridáte do súboru uložíte a VS si to načíta =>
pohodička. Potom už súbor len zduplikujete pomenujete napríklad
cs-CZ.resx
a zmeníte hodnoty na ich slovenský ekvivalent.
V aplikácii si vytvoríte nejaký ComboBox a do neho si pridáte napríklad:
English Česky
Takto by mohla vyzerať trieda LangManager
:
public static class LangManager {
Do listu Languages si dáme podporované jazyky, v rovnakom poradí ako sú v ComboBox
public static List<string> Languages = new List<string>() { "en-GB", "cs-CZ" }; public static string currentCulture; public static System.Resources.ResourceManager strings; public static void SetLangFromFile() { string culture = null; if (File.Exists(Global.appDataFolder + "lang.ini")) { using (StreamReader sr = new StreamReader(Global.appDataFolder + "lang.ini", Encoding.UTF8)) { culture = sr.ReadLine(); } } SetLanguage(culture); } public static void SaveLangToFile(string culture) { using (StreamWriter sw = new StreamWriter(Global.appDataFolder + "lang.ini", false, Encoding.UTF8)) { sw.WriteLine(culture); } } public static void SetLanguage(string culture) { if (culture == "cs-CZ") { Thread.CurrentThread.CurrentCulture = new CultureInfo("cs-CZ"); strings = Properties.Strings.cs_CZ.ResourceManager; currentCulture = "cs-CZ"; } else { Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB"); strings = Properties.Strings._default.ResourceManager; currentCulture = "en-GB"; } } public static string Translate(string name) { if (strings == null) SetLanguage(null); return strings.GetString(name); } }
Pri nastavovaní vybraného jazyka:
languageSelector.SelectedIndex = Global.LangManager.Languages.IndexOf(Global.LangManager.currentCulture);
Ukladanie vybraného jazyka:
string culture = "en-GB"; if (languageSelector.SelectedIndex != -1) culture = Global.LangManager.Languages[languageSelector.SelectedIndex]; if (Global.LangManager.currentCulture != culture) { Global.LangManager.SaveLangToFile(culture); Global.LangManager.SetLanguage(culture); Global.OpenForms.mainForm.TranslateForm(); }
Tu je vidieť, ako pošéfit preklad za behu aplikácie. Proste si urobíte nejakú metódu, ktorá preloží formulár a zavoláte ju.
No a potom už len voláte
nameTB.Text = LangManager.Translate("name");