如何用最簡單的方法讓WPF程式支援多國語言,並且語言文字使用者可以隨意編輯?

來源:互聯網
上載者:User

支援多語言的核心無非是,切換Applicaion層級的ResourceDictionary

 

語言檔案隨意編輯,無非是在程式啟動時,載入一下某個資源檔而已。

 

為了支援介面使用多語言,我們自己定義了一個Resource擴充標記。

 

同時,為了防止,使用者誤將語言資源刪除,而引起介面無任何文字的情況,我們內部定義了一個預設的資源檔,這樣就不會沒有顯示了。

 

資源檔的目錄結構:

Languages目錄下有Default.xaml, en-US.xaml, zh-CN.xaml等

 

先上核心讀取類LanguageReader:

 

#region Header/** * <pre> * *  Work Force Management *  File: LanguageReader.cs * *  Grandsys, Inc. *  Copyright (C): 2009 * *  Description: *  Init LanguageReader * *  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 LanguageReader    {        #region Fields        private const string LANGUAGE_PATH = @".\Languages\";        private const string RESOURCE_FILE = @".\Resources\ApplicationResource.xaml";        private static ResourceDictionary _currentLanguage;        private static ResourceDictionary _defaultLanguage;        #endregion Fields        static LanguageReader()        {            Uri uri = new Uri("Luna.Globalization;component/Languages/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 = CheckLanguageName(culture);            if (isExistLanguage)            {                string path = LANGUAGE_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="languageName">Name of the language.</param>        /// <returns></returns>        private static bool CheckLanguageName(string languageName)        {            var allLanguageNames = Directory.GetFiles(LANGUAGE_PATH);            foreach (var name in allLanguageNames)            {                if (name.Contains(languageName))                {                    return true;                }            }            return false;        }        #endregion Methods    }}

然後就是自己的Resource擴充標記

 

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 LanguageReader.GetValue(Key);        }        [ConstructorArgument("Key")]        public object Key        { get; set; }    }}

如何使用?

在App.config裡面配置:

 

<add key="Language" value="zh-TW" />

在App.xaml.cs的啟動時載入:

 

LanguageReader.Load(ConfigurationManager.AppSettings["Language"]);

 

 

在XAML檔案裡面使用:

 

 

<TextBlock Text="{inf:Resource OK}"/>

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.