簡體   English   中英

在WPF中更改文化后更新資源字符串(GUI中的文本)

[英]Update resource string (Text in GUI) after culture change in WPF

我正在研究WPF應用程序的本地化。 我的問題是當我從Combo Box(下拉)更改語言時,我想更新整個應用程序的文本。 但我不知道該怎么做。

我使用.resx文件作為我的資源文件。

例如,如果選擇的語言是英語,那么文本將是英語,但是當我將其更改為法語時,我想要更新法語資源文件中的按鈕文本。

對好文章的建議也是可以接受的。 我正在為大型應用尋找好的解決方案。

提前致謝。

從我看到的所有解決方案中,最好的方法是使用帶字符串的字典,綁定到動態資源和字符串管理器

using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Windows;
using System.Linq;
using System.Windows.Markup;
using Trace.Lib;

namespace Atlas.SSUP.Client.Core.Components.Managers
{
    public class StringManager
    {
        public static readonly StringManager Instance = new StringManager();

        /// <summary>
        /// Private constructor for singleton pattern
        /// </summary>
        private StringManager()
        {
        }

        private readonly CultureInfo DefaultCulture = new CultureInfo("fr-FR");

        private ResourceDictionary LanguageDictionary { get; set; }

        private Collection<ResourceDictionary> Root
        {
            get { return Application.Current.Resources.MergedDictionaries[0].MergedDictionaries; }
        }

        /// <summary>
        /// Gets a string from the common resource file.
        /// </summary>
        /// <param name="key">The key.of the desired string.</param>
        /// <returns>The string corresponding to the key provided.</returns>
        public string GetString(string key)
        {
            try
            {
                string value = LanguageDictionary[key] as string;
                if (value == null || value.Contains("String.Empty"))
                    value = string.Empty;

                return value;
            }
            catch (Exception e)
            {
                BusinessLogger.Manage(e);
                return string.Empty;
            }
        }

        public void SetCulture( string newSource )
        {
            try
            {
                ResourceDictionary langOld = Root.Single(p => p.Source.OriginalString.Contains("Strings."));
                if (langOld != null)
                {
                    ResourceDictionary lang = LoadDictionary(newSource);
                    if (lang != null)
                    {

                        Application.Current.Resources.BeginInit();

                        Root.Remove(langOld);
                        Root.Insert(0,lang);

                        Application.Current.Resources.EndInit();

                        LanguageDictionary = lang;
                    }
                }
            }
            catch (Exception e)
            {
                BusinessLogger.Manage(e);
                throw;
            }
        }


        public void Load()
        {
            Collection<ResourceDictionary> toRemove = new Collection<ResourceDictionary>();
            Collection<ResourceDictionary> toAdd = new Collection<ResourceDictionary>();

            foreach (ResourceDictionary res in Root)
            {
                if (res.Source.OriginalString.Contains("/Atlas.SSUP.Client.Core;Component/Resources/"))
                {
                    ResourceDictionary newDico = LoadDictionary(res.Source.OriginalString.Replace("/Atlas.SSUP.Client.Core;Component/Resources/", ""));
                    if (newDico != null)
                    {
                        toAdd.Add(newDico);
                        toRemove.Add(res);
                    }
                }
            }

            Application.Current.Resources.BeginInit();

            foreach (ResourceDictionary res in toRemove)
                Root.Remove(res);
            foreach (ResourceDictionary res in toAdd)
                Root.Add(res);

            Application.Current.Resources.EndInit();
        }

        private ResourceDictionary LoadDictionary(string source)
        {
            Stream streamInfo = null;
            ResourceDictionary dictionary = null;

            try
            {
                streamInfo = DistantManager.Instance.GetResource(source);

                if (streamInfo != null)
                {
                    Uri baseUri = DistantManager.Instance.GetUri(source);

                    dictionary = XamlReader.Load(streamInfo) as ResourceDictionary;

                    dictionary.Source = baseUri;
                }
            }
            catch (Exception e)
            {
                BusinessLogger.Manage(e);
                return null;
            }

            return dictionary;
        }
    }
}

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:w="clr-namespace:System.Windows;assembly=PresentationCore">

<!-- Font size on map station labels -->
<s:Double x:Key="StationFontSize">12</s:Double>

<!-- FlowDirection LeftToRight ou RightToLeft -->
<w:FlowDirection x:Key="FlowDirection">LeftToRight</w:FlowDirection>

<!-- Dialog -->
<s:String x:Key="String.Dialog.OK">OK</s:String>
<s:String x:Key="String.Dialog.Cancel">Cancel</s:String>
<s:String x:Key="String.Dialog.Yes">Yes</s:String>
<s:String x:Key="String.Dialog.No">No</s:String>

或者你在這里有另一個解決方案,但更復雜的cbr

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM