之前寫過(guò)winformwinform使用本地化,中英文切換_winform 中英文切換_故里2130的博客-CSDN博客
基本的技術(shù)差不多,但是后來(lái)又發(fā)現(xiàn)了一個(gè)ResXManager工具,可以更好方便快捷的使用。
首先下載,網(wǎng)絡(luò)不好的話,去官網(wǎng)下載,然后安裝,重啟vs即可
wpf做多語(yǔ)言切換
有很多種,可以使用自帶的資源去做,就是使用xaml寫key值,這種做法是最簡(jiǎn)單方便的,也是wpf獨(dú)特使用的,如果有大量的翻譯,那么需要人工去翻譯,需要轉(zhuǎn)折一次,此種方法就不說(shuō)了。下面說(shuō)2種使用.resx資源和ResXManager工具來(lái)做。唯一的好處,就是自帶翻譯功能,方便快捷。
第一種
1.此處使用.net6創(chuàng)建wpf項(xiàng)目,與.net?framework不一樣,.net?framework要簡(jiǎn)單一些
建立如圖項(xiàng)目
2.打開(kāi)ResXManager工具
3.點(diǎn)擊新增語(yǔ)言,增加幾個(gè)語(yǔ)種
增加后,雙擊增加的語(yǔ)種,就會(huì)自動(dòng)生成對(duì)應(yīng)的.resx文件,想要多少種語(yǔ)言,就可以增加多少種
最后要修改一下后綴名,否則報(bào)錯(cuò)。
4. 點(diǎn)擊翻譯
此處,可以導(dǎo)出Excel,讓別人翻譯,然后再導(dǎo)入,也可以使用在線翻譯的功能,點(diǎn)擊翻譯。
??
5.效果
6. 創(chuàng)建LanguageManager.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Resources;
using System.Text;
namespace WpfApp1.Resources
{
public class LanguageManager : INotifyPropertyChanged
{
/// <summary>
/// 資源
/// </summary>
private readonly ResourceManager _resourceManager;
/// <summary>
/// 懶加載
/// </summary>
private static readonly Lazy<LanguageManager> _lazy = new Lazy<LanguageManager>(() => new LanguageManager());
public static LanguageManager Instance => _lazy.Value;
public event PropertyChangedEventHandler PropertyChanged;
public LanguageManager()
{
//獲取此命名空間下Resources的Lang的資源,Lang可以修改
_resourceManager = new ResourceManager("WpfApp1.Resources.Lang", typeof(LanguageManager).Assembly);
}
/// <summary>
/// 索引器的寫法,傳入字符串的下標(biāo)
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public string this[string name]
{
get
{
if (name == null)
{
throw new ArgumentNullException(nameof(name));
}
return _resourceManager.GetString(name);
}
}
public void ChangeLanguage(CultureInfo cultureInfo)
{
CultureInfo.CurrentCulture = cultureInfo;
CultureInfo.CurrentUICulture = cultureInfo;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("item[]")); //字符串集合,對(duì)應(yīng)資源的值
}
}
}
7.xaml界面
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1.Resources"
mc:Ignorable="d"
xmlns:res="clr-namespace:System.Windows.Resources;assembly=PresentationFramework"
Title="MainWindow" Height="450" Width="800">
<StackPanel HorizontalAlignment="Center">
<ComboBox x:Name="LanguageList" SelectedIndex="0" Margin="10" SelectionChanged="LanguageList_SelectionChanged"/>
<!--這里綁定字符串的值,Source來(lái)源于語(yǔ)言的集合,Mode是響應(yīng)的方式,有些需要,有些不需要-->
<TextBlock FontSize="20" Margin="10" Text="{Binding [String1], Source={x:Static local:LanguageManager.Instance}}"/>
<TextBox FontSize="20" Margin="10" Text="{Binding [String2], Source={x:Static local:LanguageManager.Instance}, Mode=OneWay}"/>
<Button FontSize="20" Margin="10" Content="{Binding [String3], Source={x:Static local:LanguageManager.Instance}}"/>
</StackPanel>
</Window>
8.后臺(tái)
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WpfApp1.Resources;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
LanguageList.ItemsSource = new List<string>
{
"en-Us",
"zh-CN",
"ar"
};
//this.DataContext = new Lazy<LanguageManager>(() => new LanguageManager()).Value;
}
/// <summary>
/// 下拉框賦值語(yǔ)言的類型
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void LanguageList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
LanguageManager.Instance.ChangeLanguage(new CultureInfo((sender as ComboBox).SelectedItem.ToString()));
}
}
}
此處使用mvvm的話,可以直接綁定,1對(duì)1綁定語(yǔ)言?
9.效果
第二種
1.首先創(chuàng)建一個(gè)程序
2.在Resources文件夾中,創(chuàng)建文件
3.GlobalClass.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
namespace WpfApp2.Resources
{
/// <summary>
/// 全局類
/// </summary>
public static class GlobalClass
{
static bool? inDesignMode = null;
/// <summary>
/// 判斷是設(shè)計(jì)器還是程序運(yùn)行
/// </summary>
public static bool InDesignMode
{
get
{
if (inDesignMode == null)
{
#if SILVERLIGHT
inDesignMode = DesignerProperties.IsInDesignTool;
#else
var prop = DesignerProperties.IsInDesignModeProperty;
inDesignMode = (bool)DependencyPropertyDescriptor.FromProperty(prop, typeof(FrameworkElement)).Metadata.DefaultValue;
if (!inDesignMode.GetValueOrDefault(false) && Process.GetCurrentProcess().ProcessName.StartsWith("devenv", StringComparison.Ordinal))
inDesignMode = true;
#endif
}
return inDesignMode.GetValueOrDefault(false);
}
}
/// <summary>
/// 語(yǔ)言改變通知事件
/// </summary>
public static EventHandler<EventArgs> LanguageChangeEvent;
static Resource StringResource;
static GlobalClass()
{
StringResource = new Resource();
}
/// <summary>
/// 獲取資源內(nèi)容
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static string GetString(string key)
{
return StringResource.GetString(key);
}
/// <summary>
/// 改變語(yǔ)言
/// </summary>
/// <param name="language">CultureInfo列表(http://www.csharpwin.com/csharpspace/8948r7277.shtml)</param>
public static void ChangeLanguage(string language)
{
CultureInfo culture = new CultureInfo(language);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
StringResource.CurrentCulture = culture;
if (LanguageChangeEvent != null)
{
LanguageChangeEvent(null, null);
}
}
}
}
4.Resource.cs
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Resources;
namespace WpfApp2.Resources
{
public interface IResource
{
string GetString(string name);
CultureInfo CurrentCulture { set; }
}
public class Resource : IResource
{
private ResourceManager stringResource;
//我們這樣設(shè)置的時(shí)候ResourceManager會(huì)去查找MultilanguageTest.StringResource.en-us.resx,如果沒(méi)有會(huì)查找MultilanguageTest.StringResource.resx
private CultureInfo culture = new CultureInfo("zh-cn"); //默認(rèn)值
public Resource()
{
//MultilanguageTest.StringResource是根名稱,該實(shí)例使用指定的System.Reflection.Assmbly查找從指定的跟名稱導(dǎo)出的文件中包含的資源
//此處注意WpfApp2.Resources.Lang,Lang是資源文件的名字
stringResource = new ResourceManager("WpfApp2.Resources.Lang", typeof(Resource).Assembly);
}
/// <summary>
/// 通過(guò)資源名稱獲取資源內(nèi)容
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public string GetString(string name)
{
return stringResource.GetString(name, culture);
}
/// <summary>
/// 改變當(dāng)前的區(qū)域信息,ResourceManager可以通過(guò)當(dāng)前區(qū)域信息去查找.resx文件
/// </summary>
public CultureInfo CurrentCulture
{
set
{
culture = value;
}
}
}
}
5.StringResourceExtension.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;
namespace WpfApp2.Resources
{
[MarkupExtensionReturnType(typeof(BindingExpression))]
public class StringResourceExtension : MarkupExtension, INotifyPropertyChanged
{
/// <summary>
/// 資源的名稱,與資源文件StringResource.resx對(duì)應(yīng)
/// </summary>
[ConstructorArgument("key")]
public string Key
{
get;
set;
}
string _DefaultValue;
/// <summary>
/// 默認(rèn)值,為了使在設(shè)計(jì)器的情況時(shí)把默認(rèn)值綁到設(shè)計(jì)器
/// </summary>
public string DefaultValue
{
get
{
return _DefaultValue;
}
set
{
_DefaultValue = value;
}
}
string _Value;
/// <summary>
/// 資源的具體內(nèi)容,通過(guò)資源名稱也就是上面的Key找到對(duì)應(yīng)內(nèi)容
/// </summary>
public string Value
{
get
{
///如果為設(shè)計(jì)器模式,本地的資源沒(méi)有實(shí)例化,我們不能從資源文件得到內(nèi)容,所以從KEY或默認(rèn)值綁定到設(shè)計(jì)器去
if (GlobalClass.InDesignMode)
{
if (Key != null && DefaultValue != null)
return DefaultValue;
if (Key == null && DefaultValue != null)
return DefaultValue;
if (Key != null && DefaultValue == null)
return Key;
if (Key == null && DefaultValue == null)
return "NULL";
}
else
{
if (Key != null)
{
string strResault = null;
try
{
strResault = GlobalClass.GetString(Key);
}
catch
{
}
if (strResault == null)
{
strResault = _DefaultValue;
}
return strResault;
}
}
return _Value;
}
set
{
_Value = value;
}
}
public StringResourceExtension(string key)
: this()
{
Key = key;
GlobalClass.LanguageChangeEvent += new EventHandler<EventArgs>(Language_Event);
}
public StringResourceExtension(string key, string DefaultValue)
: this()
{
Key = key;
_DefaultValue = DefaultValue;
GlobalClass.LanguageChangeEvent += new EventHandler<EventArgs>(Language_Event);
}
public StringResourceExtension()
{
}
/// <summary>
/// 每一標(biāo)記擴(kuò)展實(shí)現(xiàn)的 ProvideValue 方法能在可提供上下文的運(yùn)行時(shí)使用 IServiceProvider。然后會(huì)查詢此 IServiceProvider 以獲取傳遞信息的特定服務(wù)
///當(dāng) XAML 處理器在處理一個(gè)類型節(jié)點(diǎn)和成員值,且該成員值是標(biāo)記擴(kuò)展時(shí),它將調(diào)用該標(biāo)記擴(kuò)展的 ProvideValue 方法并將結(jié)果寫入到對(duì)象關(guān)系圖或序列化流,XAML 對(duì)象編寫器將服務(wù)環(huán)境通過(guò) serviceProvider 參數(shù)傳遞到每個(gè)此類實(shí)現(xiàn)。
/// </summary>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public override object ProvideValue(IServiceProvider serviceProvider)
{
IProvideValueTarget target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
Setter setter = target.TargetObject as Setter;
if (setter != null)
{
return new Binding("Value") { Source = this, Mode = BindingMode.OneWay };
}
else
{
Binding binding = new Binding("Value") { Source = this, Mode = BindingMode.OneWay };
return binding.ProvideValue(serviceProvider);
}
}
public event PropertyChangedEventHandler PropertyChanged;
static readonly System.ComponentModel.PropertyChangedEventArgs
valueChangedEventArgs = new System.ComponentModel.PropertyChangedEventArgs("Value");
protected void NotifyValueChanged()
{
if (PropertyChanged != null)
PropertyChanged(this, valueChangedEventArgs);
}
/// <summary>
/// 語(yǔ)言改變通知事件,當(dāng)程序初始化的時(shí)候會(huì)綁定到全局的GlobalClass.LanguageChangeEvent事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Language_Event(object sender, EventArgs e)
{
//通知Value值已經(jīng)改變,需重新獲取
NotifyValueChanged();
}
}
}
6.創(chuàng)建3個(gè)語(yǔ)言的文件
使用ResXManager工具進(jìn)行翻譯,參考上面的細(xì)節(jié)
7.效果
2種方式都可以,第一種要簡(jiǎn)單一點(diǎn)。?
源碼:
https://download.csdn.net/download/u012563853/87944124文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-500007.html
來(lái)源:WPF本地化/國(guó)際化,多語(yǔ)言切換_wpf 國(guó)際化_故里2130的博客-CSDN博客文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-500007.html
到了這里,關(guān)于WPF本地化/國(guó)際化,多語(yǔ)言切換的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!