WPF中区域性更改后更新资源字符串(GUI中的文本)
本文关键字:GUI 文本 字符串 更新 区域性 WPF 资源 | 更新日期: 2023-09-27 18:10:44
我正在研究WPF应用程序的本地化。我的问题是,当我从组合框(下拉)更改语言时,我想更新整个应用程序的文本。但我不知道该怎么做。
我使用。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