在WPF项目中,我们可以新建XAML,新建一个ResourceDictionary
,存放字符串;XAML显示时使用{DynamicResource xxxx}
的方式,来实现动态的多语言功能。(比如这篇文章就是这样做的)
在Avalonia
中,我们也可以使用类似的方法来实现这个功能。
准备工作
这里我们直接新建一个Avalonia MVVM
的工程模板。
我们在Assets
文件夹下新建一个Languages
文件夹,然后在其中新建zh-CN.axaml
与en-US.axaml
。
我们在其中填入以下内容:
zh-CN.axaml
<ResourceDictionary
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:String x:Key="JustTest">只是个测试</system:String>
</ResourceDictionary>
en-US.axaml
<ResourceDictionary
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:String x:Key="JustTest">Just a test</system:String>
</ResourceDictionary>
使用ResourceDictionary里的内容
在App.axaml
中,我们在Application
层级下添加一个Resources
数据(如果已有Resources
项,就加入其中),在其中放入一个ResourceDictionary
数据:
<Application
...>
...
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceInclude Source="/Assets/Languages/zh-CN.axaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
...
</Application>
这是我们就可以在其他xaml中使用这个默认的资源了,比如我们在MainWindow.axaml
里加上下面的内容:
...
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="{DynamicResource JustTest}" />
...
这里的DynamicResource
就可以直接调用ResourceDictionary
中对应的数据
切换资源文件实现切换语言功能
切换语言资源文件十分简单,只需要把对应的Resources
内容换掉就可以。
比如我们这里的语言文件是第一个Resources
,那么可以直接用如下函数替换资源:
public static void ChangeLanguage(string language)
{
var file = $"avares://TestLanguages/Assets/Languages/{language}.axaml";
var data = new ResourceInclude(new Uri(file, UriKind.Absolute));
data.Source = new Uri(file, UriKind.Absolute);
Avalonia.Application.Current!.Resources.MergedDictionaries[0] = data;
}
我们可以在MainWindow.axaml
里加上两个按钮测试一下功能是否正常:
...
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="{DynamicResource JustTest}" />
<Button Click="ButtonClicked" Content="zh-CN" />
<Button Click="ButtonClicked" Content="en-US" />
</StackPanel>
...
MainWindow.axaml.cs
里的按键事件:
private void ButtonClicked(object sender, Avalonia.Interactivity.RoutedEventArgs e)
{
var language = ((Button)sender).Content.ToString();
Utils.ChangeLanguage(language);
//我把ChangeLanguage函数放进了Utils类里,这里按你实际的位置调用它即可
}
这样就可以实现动态的切换语言了
在C#中获取资源值
既然xaml里可以使用多语言,那么C#代码中也一定有获取这些值的需求,实际也很简单。
这些资源不一定都是字符串,所以我这里封装为泛型的接口,这样更通用,可以直接通过名称获取对应的值:
public static T GetLanguageResource<T>(string name)
{
try
{
Avalonia.Application.Current!.TryFindResource(name, out object value);
return (T)value;
}
catch
{
if (typeof(T) == typeof(string))
return (T)(object)"??";
else
return default!;
}
}
END
基本要用到的就是这些了,和WPF的逻辑区别不大,只是加载逻辑不太一样而已。