xamarin.forms: 在运行时更改语言不会影响 UI 你好
xamarin.forms: Changing language at runtim doesnt affect UI Hi
我有一个应用程序,用户可以在其中选择他或她的语言:
我有两个资源文件,它们都可以工作,因为我可以看到显示在 Xaml 中的文本。
简短概述:
英语资源:
<data name="Next" xml:space="preserve">
<value>next</value>
</data>
<data name="German" xml:space="preserve">
<value>German</value>
</data>
<data name="Arabic" xml:space="preserve">
<value>Arabic</value>
</data>
标签:
<Label Text="{x:Static resources:AppResources.German}"
VerticalOptions="Center"
Grid.Row="0"/>
<Label Text="{x:Static resources:AppResources.Arabic}"
VerticalOptions="Center"
Grid.Row="1"/>
<Label Text="{x:Static resources:AppResources.English}"
VerticalOptions="Center"
Grid.Row="2"/>
我知道它们可以工作,因为当我从一个模拟器切换到另一个(一个在德国,一个在英国)时,语言会自动改变。
但我希望用户能够在单击按钮时更改语言。
我试过了:
case "english":
CultureInfo culture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentCulture = culture;
mainPage.FlowDirection = FlowDirection.LeftToRight;
break;
但是 phone 只是忽略了语言变化。
知道为什么吗?
您可以创建一个 LocalizationResourceManager
class 来处理语言更改,并且还会有一个带有翻译的 属性。当语言更改时,它会使该字符串无效,因此它将强制 属性 更改。
public class LocalizationResourceManager : INotifyPropertyChanged
{
public static LocalizationResourceManager Instance { get; } = new LocalizationResourceManager();
public string this[string text]
{
get
{
return AppResources.ResourceManager.GetString(text, AppResources.Culture);
}
}
public void SetCulture(CultureInfo language)
{
Thread.CurrentThread.CurrentUICulture = language;
AppResources.Culture = language;
Invalidate();
}
public event PropertyChangedEventHandler PropertyChanged;
public void Invalidate()
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
}
}
不是将我们的字符串直接绑定到 AppResources
class,而是使用 returns 和 BindingProperty
的翻译扩展并绑定到我们的新 LocalizationResourceManager
.
[ContentProperty("Text")]
public class TranslateExtension : IMarkupExtension<BindingBase>
{
public string Text { get; set; }
public string StringFormat { get; set; }
object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
{
return ProvideValue(serviceProvider);
}
public BindingBase ProvideValue(IServiceProvider serviceProvider)
{
var binding = new Binding
{
Mode = BindingMode.OneWay,
Path = $"[{Text}]",
Source = LocalizationResourceManager.Instance,
StringFormat= StringFormat
};
return binding;
}
}
用法:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MultilingualXFSample.Views.ChangeLanguagePage"
xmlns:helpers="clr-namespace:MultilingualXFSample.Helpers">
<Label Text="{helpers:Translate SelectLanguage}" />
</ContentPage>
更多可以查看:Mastering Multilingual in Xamarin.Forms
这里有一个示例:https://github.com/CrossGeeks/MasteringMultilingualSample .
我有一个应用程序,用户可以在其中选择他或她的语言:
我有两个资源文件,它们都可以工作,因为我可以看到显示在 Xaml 中的文本。
简短概述:
英语资源:
<data name="Next" xml:space="preserve">
<value>next</value>
</data>
<data name="German" xml:space="preserve">
<value>German</value>
</data>
<data name="Arabic" xml:space="preserve">
<value>Arabic</value>
</data>
标签:
<Label Text="{x:Static resources:AppResources.German}"
VerticalOptions="Center"
Grid.Row="0"/>
<Label Text="{x:Static resources:AppResources.Arabic}"
VerticalOptions="Center"
Grid.Row="1"/>
<Label Text="{x:Static resources:AppResources.English}"
VerticalOptions="Center"
Grid.Row="2"/>
我知道它们可以工作,因为当我从一个模拟器切换到另一个(一个在德国,一个在英国)时,语言会自动改变。
但我希望用户能够在单击按钮时更改语言。
我试过了:
case "english":
CultureInfo culture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentCulture = culture;
mainPage.FlowDirection = FlowDirection.LeftToRight;
break;
但是 phone 只是忽略了语言变化。
知道为什么吗?
您可以创建一个 LocalizationResourceManager
class 来处理语言更改,并且还会有一个带有翻译的 属性。当语言更改时,它会使该字符串无效,因此它将强制 属性 更改。
public class LocalizationResourceManager : INotifyPropertyChanged
{
public static LocalizationResourceManager Instance { get; } = new LocalizationResourceManager();
public string this[string text]
{
get
{
return AppResources.ResourceManager.GetString(text, AppResources.Culture);
}
}
public void SetCulture(CultureInfo language)
{
Thread.CurrentThread.CurrentUICulture = language;
AppResources.Culture = language;
Invalidate();
}
public event PropertyChangedEventHandler PropertyChanged;
public void Invalidate()
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
}
}
不是将我们的字符串直接绑定到 AppResources
class,而是使用 returns 和 BindingProperty
的翻译扩展并绑定到我们的新 LocalizationResourceManager
.
[ContentProperty("Text")]
public class TranslateExtension : IMarkupExtension<BindingBase>
{
public string Text { get; set; }
public string StringFormat { get; set; }
object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
{
return ProvideValue(serviceProvider);
}
public BindingBase ProvideValue(IServiceProvider serviceProvider)
{
var binding = new Binding
{
Mode = BindingMode.OneWay,
Path = $"[{Text}]",
Source = LocalizationResourceManager.Instance,
StringFormat= StringFormat
};
return binding;
}
}
用法:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MultilingualXFSample.Views.ChangeLanguagePage"
xmlns:helpers="clr-namespace:MultilingualXFSample.Helpers">
<Label Text="{helpers:Translate SelectLanguage}" />
</ContentPage>
更多可以查看:Mastering Multilingual in Xamarin.Forms
这里有一个示例:https://github.com/CrossGeeks/MasteringMultilingualSample .