The foundation consists of 5 classes – RL, Translation, AppLangConverter, AppLang and AppLangHelper – and the Langs enum. From the code you can tell that a program can have at most 10 languages (it is a single digit, so 0-9). So now I will serve you all of these classes, enums and how it is used in practice:
RL:
CODE
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
/// <summary>
/// Static class that stores the Czech text and the English translation under individual keys
/// It has a method for returning the text based on the given language.
/// </summary>
public static class Localizer
{
public static Langs l = Langs.en;
static Dictionary<string, string> en = new Dictionary<string, string>();
static Dictionary<string, string> cs = new Dictionary<string, string>();
public static void Initialize(Dictionary<string, Translation> translations)
{
foreach (var item in translations)
{
en.Add(item.Key, item.Value.En);
cs.Add(item.Key, item.Value.Cs);
}
}
public static string GetString(string k)
{
if (l == Langs.cs)
{
return cs[k];
}
return en[k];
}
}Translation:
CODE
/// <summary>
/// Data class containing only the Czech text and its corresponding English translation
/// </summary>
public class Translation
{
public string En = null;
public string Cs = null;
public Translation(string en, string cs)
{
En = en;
Cs = cs;
}
}AppLangConverter:
CODE
using swf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
/// <summary>
/// Static conversion class that converts all data from the AppLang class to a string and back
/// </summary>
public static class AppLangConverter
{
public static AppLang ConvertTo(string b)
{
byte type = 0;
if (!byte.TryParse(b[0].ToString(), out type))
{
return new AppLang(1, 0);
}
byte lang = 0;
if (!byte.TryParse(b[1].ToString(), out lang))
{
return new AppLang(1, 0);
}
return new AppLang(type, lang);
}
public static string ConvertFrom(AppLang t)
{
return t.Type.ToString() + t.Language.ToString();
}
}AppLang:
CODE
/// <summary>
/// AppLang is just a data class containing a two-digit number. If the first digit is 0, the second digit is the ID of the language that will be set as fixed. If the first digit is 1, the language will be set according to the system.
/// </summary>
public class AppLang
{
byte language = 0;
byte type = 0;
/// <summary>
/// If it is the system language, with value 0 the language is taken from CurrentUICulture, whereas with value 1 it is taken from CurrentCulture
/// </summary>
public byte Language
{
get
{
return language;
}
}
/// <summary>
/// Language type, whether fixed or system
///
/// </summary>
public byte Type
{
get
{
return type;
}
}
/// <summary>
/// Performance comes first here, which is why this class has no Parse method and no parameterless constructor.
/// </summary>
/// <param name="type"></param>
/// <param name="language"></param>
public AppLang(byte type, byte language)
{
this.type = type;
this.language = language;
}
public override string ToString()
{
return AppLangHelper.ToString(this);
}
}AppLangHelper:
CODE
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Controls;
public static class AppLangHelper
{
public static CultureInfo currentCulture = null;
public static CultureInfo currentUICulture = null;
/// <summary>
/// Languages the user can choose themselves
/// The key is the language abbreviation, the value is its full name
/// </summary>
static Dictionary<string, string> fixedLanguages = new Dictionary<string, string>();
/// <summary>
/// Texts for the languages
/// The key is the two-letter language name, the value is the texts "Podle nastaveneho jazyka OS" and "Depending on the OS language"
/// </summary>
static Dictionary<string, List<string>> systemLanguages = new Dictionary<string, List<string>>();
/// <summary>
/// The key is the two-letter language name, the value is the number of this language used in the AppLang class
/// </summary>
static Dictionary<string, byte> languageCodes = new Dictionary<string, byte>();
/// <summary>
/// Number 0
/// </summary>
const byte fixedType = 0;
/// <summary>
/// Number 1
/// </summary>
const byte systemType = 1;
const byte dependingOnLanguage = 0;
/// <summary>
/// The text Podle nastaveneho jazyka OS
/// Although it has 0 in its name, it is used when the language type is not 0
/// </summary>
const string csSystemLanguageText = "Podle nastaveneho jazyka OS";
/// <summary>
/// The text Depending on the OS language
/// Although it has 0 in its name, it is used when the language type is not 0
/// </summary>
const string enSystemLanguageText = "Depending on the OS language";
public static AppLang selectedLanguage = null;
static AppLangHelper()
{
fixedLanguages.Add("cs", "Cestina");
fixedLanguages.Add("en", "English");
List<string> systemLanguageCS = new List<string>();
systemLanguageCS.Add(csSystemLanguageText);
List<string> systemLanguageEN = new List<string>();
systemLanguageEN.Add(enSystemLanguageText);
systemLanguages.Add("cs", systemLanguageCS);
systemLanguages.Add("en", systemLanguageEN);
}
/// <summary>
/// Returns the language name, for example for a ComboBox used to change the language
/// If A1.Type is not 0, returns the correct text according to the OS language
/// </summary>
/// <param name="actual"></param>
/// <param name="displayed"></param>
/// <returns></returns>
public static string ToString(AppLang actual)
{
string vr = "";
if (actual.Type == fixedType)
{
vr = fixedLanguages[((Langs)actual.Language).ToString()];
}
else
{
CultureInfo depending = null;
if (actual.Language == dependingOnLanguage)
{
depending = currentUICulture;
}
else
{
depending = currentCulture;
}
if (depending == null)
{
if (actual.Language == dependingOnLanguage)
{
depending = CultureInfo.CurrentUICulture;
}
else
{
depending = CultureInfo.CurrentCulture;
}
}
if (depending.TwoLetterISOLanguageName == "cs")
{
//-OK, the current language is based on CultureInfo.CurrentUICulture.TwoLetterISOLanguageName
if (actual.Language == 0)
{
vr = csSystemLanguageText + " - " + fixedLanguages[CultureInfo.CurrentUICulture.TwoLetterISOLanguageName];
}
}
else //if (depending.TwoLetterISOLanguageName == "en")
{
if (actual.Language == 0)
{
vr = enSystemLanguageText + " - " + fixedLanguages[CultureInfo.CurrentUICulture.TwoLetterISOLanguageName];
}
}
}
return vr;
}
/// <summary>
/// Method that returns the language in which the content should be displayed
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
public static Langs GetLang(string b)
{
Langs vr = Langs.cs;
AppLang actual = AppLangConverter.ConvertTo(b);
if (actual.Type == fixedType)
{
vr = (Langs)actual.Language;
}
else
{
//-OK, the current language is based on CultureInfo.CurrentUICulture.TwoLetterISOLanguageName
if (actual.Language == 0)
{
vr = ParseLang(CultureInfo.CurrentUICulture.TwoLetterISOLanguageName);
}
else if (actual.Language == 1)
{
vr = ParseLang(CultureInfo.CurrentCulture.TwoLetterISOLanguageName);
}
}
return vr;
}
/// <summary>
/// Used when I want to return the language as the Langs enum - A1 must be a member of the Langs enum, i.e. cs or en
/// It has 2 in its name because the same method already exists, but that one also returns the language according to the OS
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
private static Langs ParseLang(string p)
{
Langs vr = Langs.cs;
if (Enum.TryParse<Langs>(p, out vr))
{
return vr;
}
return Langs.en;
}
/// <summary>
/// Returns the CultureInfo of the given country without a language specification for the language A1
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
public static CultureInfo GetCultureInfo(Langs p)
{
CultureInfo culture = null;
if (p == Langs.cs)
{
culture = new CultureInfo("cs");
}
else
{
culture = new CultureInfo("en");
}
return culture;
}
/// <summary>
/// Returns the Langs enum, i.e. the language based on A1
/// </summary>
/// <param name="cultureInfo"></param>
/// <returns></returns>
public static Langs GetLang(CultureInfo cultureInfo)
{
if (cultureInfo.TwoLetterISOLanguageName == "cs")
{
return Langs.cs;
}
else
{
return Langs.en;
}
}
/// <summary>
/// Adds items to A1 - first the fixed languages and then the OS-based ones in the OS language
/// If the output of the AppLangConverter.ConvertFrom method for the current iteration equals A2, the item is selected.
/// </summary>
/// <param name="comboBox"></param>
/// <param name="settingsAl"></param>
public static void AddItemsToComboBox(ComboBox comboBox, string settingsAl)
{
selectedLanguage = null;
byte i = 0;
foreach (var item in fixedLanguages)
{
AppLang al = new AppLang(fixedType, i);
comboBox.Items.Add(al);
if (selectedLanguage == null)
{
if (AppLangConverter.ConvertFrom(al) == settingsAl)
{
selectedLanguage = al;
}
}
i++;
}
if (CultureInfo.CurrentUICulture.TwoLetterISOLanguageName == "cs")
{
i = 0;
foreach (var item in systemLanguages["cs"])
{
AppLang al = new AppLang(systemType, i);
comboBox.Items.Add(al);
if (selectedLanguage == null)
{
if (AppLangConverter.ConvertFrom(al) == settingsAl)
{
selectedLanguage = al;
}
}
i++;
}
}
else
{
i = 0;
foreach (var item in systemLanguages["en"])
{
AppLang al = new AppLang(systemType, i);
comboBox.Items.Add(al);
if (selectedLanguage == null)
{
if (AppLangConverter.ConvertFrom(al) == settingsAl)
{
selectedLanguage = al;
}
}
i++;
}
}
comboBox.SelectedItem = selectedLanguage;
//-This should hopefully never happen
}
}Langs:
CODE
public enum Langs : byte
{
cs = 0,
en = 1
}Unique to each application:
CODE
//-I create a dictionary with keys matching the items that will be filled, plus the English text and the Czech translation
Dictionary<string, Translation> translations = new Dictionary<string, Translation>();
translations.Add("btnAddFolder.Content", new Translation("Add folders", "Pridat slozky"));
//-
Localizer.Initialize(translations);
//-Here you can also set a fixed language, or use the CultureInfo class to set the language according to the system
//-Here I load the language from a file, so the program remembers it
Localizer.l = AppLangHelper.GetLang(SunamoAlarmSettings.Language);
//-I store the Langs enum from RL.l in a local variable for easier access
l = Localizer.l;
//-After that you just set the linguistically correct text everywhere like this
btnAddFolder.Content = Localizer.GetString("btnAddFolder.Content");