The core of multi-language support is to switch the Applicaion-level resourcedictionary.
The language file can be edited at will.ProgramLoad a resource file at startup.
To support multiple languages on the interface, we define a resource extension tag.
In addition, in order to prevent users from mistakenly deleting language resources and without any text on the interface, we define a default resource file internally so that it will not be displayed.
The directory structure of the resource file:
There are default. XAML, en-US.xaml, zh-CN.xaml, etc. under the ages directory
First, read the class cyclagereader from the core:
# Region Header/*** <PRE> ** work force management * file: languagereader. CS ** grandsys, Inc. * copyright (c): 2009 ** Description: * init your agereader ** note * created by: Prime Li at 7/15/2009 2:10:04 PM ** </PRE> */# endregion headernamespace Luna. globalization {using system; using system. globalization; using system. io; using system. windows; using system. windows. markup; // <summary> // read the language // </Summary> Public static class extends agereader {# region fields private const string extends age_path = @". \ ages \ "; private const string resource_file = @". \ resources \ applicationresource. XAML "; Private Static resourcedictionary _ currentlanguage; Private Static resourcedictionary _ defaultlanguage; # endregion fields static register agereader () {URI uri = new uri (" Luna. globalization; component/ages/default. XAML ", urikind. relativeorabsolute); _ defaultlanguage = application. loadcomponent (URI) as resourcedictionary; _ currentlanguage = _ defaultlanguage;} # Region Methods // <summary> // loads the specified culture. /// </Summary> /// <Param name = "culture"> the culture. </param> Public static void load (string culture) {bool isexistlanguage = check1_agename (Culture); If (isexistlanguage) {string Path = export age_path + culture + ". XAML "; using (filestream FS = file. openread (PATH) {_ currentlanguage = xamlreader. load (FS) as resourcedictionary; If (application. current. resources. mergeddictionaries. contains (_ currentlanguage) {application. current. resources. mergeddictionaries. remove (_ currentlanguage);} application. current. resources. mergeddictionaries. add (_ currentlanguage);} application. current. dispatcher. thread. currentculture = cultureinfo. getcultureinfo (Culture); application. current. dispatcher. thread. currentuiculture = cultureinfo. getcultureinfo (Culture);} else {// use default language application. current. dispatcher. thread. currentculture = cultureinfo. getcultureinfo ("ZH-CN"); application. current. dispatcher. thread. currentuiculture = cultureinfo. getcultureinfo ("ZH-CN") ;}} public static void loadresource (string filename) {If (file. exists (filename) {using (filestream FS = file. openread (filename) {resourcedictionary DIC = xamlreader. load (FS) as resourcedictionary; application. current. resources. mergeddictionaries. add (DIC) ;}} public static void loaddefaultresource () {loadresource (resource_file);} // <summary> // gets the value. /// </Summary> /// <Param name = "key"> the key. </param> // <returns> </returns> Public static string getvalue (string key) {object value = getvalue (object) Key ); if (value = NULL) return string. empty; return value. tostring ();} // <summary> // gets the value. /// </Summary> /// <Param name = "key"> the key. </param> // <returns> </returns> Public static object getvalue (Object key) {object value = _ currentlanguage [Key]; If (value = NULL) value = _ defaultlanguage [Key]; Return Value ;}/// <summary> // gets the value. /// </Summary> /// <typeparam name = "T"> </typeparam> /// <Param name = "key"> the key. </param> // <returns> </returns> Public static t getvalue <t> (Object key) {object value = getvalue (key ); if (value = NULL) return default (t); Return (t) value;} public static bool containskey (string key) {return containskey (object) Key );} public static bool containskey (Object key) {return _ currentlanguage. contains (key) | _ defaultlanguage. contains (key);} // <summary> // checks the name of the language. /// </Summary> /// <Param name = "Your agename"> name of the language. </param> /// <returns> </returns> Private Static bool check‑agename (string ‑agename) {var all‑agenames = directory. getfiles (export age_path); foreach (VAR name in allvariables agenames) {If (name. contains (languagename) {return true ;}} return false ;}# endregion Methods }}
Then there is your own resource extension tag.
Using system; using system. windows; using system. windows. markup; namespace Luna. globalization {[markupextensionreturntype (typeof (object), Localizability (localizationcategory. neverlocalize)] public class resourceextension: markupextension {public resourceextension () {} public resourceextension (Object key) {key = key;} public override object providevalue (iserviceprovider serviceprovider) {return response agereader. getvalue (key);} [constructorargument ("key")] public object key {Get; Set ;}}}
How to use it?
Configure in APP. config:
<Add key = "language" value = "ZH-tw"/>
Load When app. XAML. CS is started:
Configuragereader. Load (configurationmanager. configurettings ["language"]);
In the XAML file, use:
<Textblock text = "{INF: Resource OK}"/>