文本块绑定 属性 更改在 UWP 中不起作用
Textblock binding property changed not working in UWP
我正在尝试实现一个简单的 "press a button to change the App language and all dependent strings" 示例。 (你可以在this GitHub repository看到完整的代码)
在此示例中,我将三个 TextBlock
和一个按钮绑定到我的语言资源:
并且:
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Vertical">
<TextBlock
HorizontalAlignment="Center"
FontSize="20"
Text="{Binding Source={StaticResource Localized}, Path=[A]}" />
<TextBlock
HorizontalAlignment="Center"
FontSize="20"
Text="{Binding Source={StaticResource Localized}, Path=[B]}" />
<TextBlock
HorizontalAlignment="Center"
FontSize="20"
Text="{Binding Source={StaticResource Localized}, Path=[C]}" />
<Button
x:Name="btnChangeLanguage"
Margin="10"
Padding="10"
Click="btnChangeLanguage_Click"
Content="{Binding Source={StaticResource Localized}, Path=[Change]}" />
</StackPanel>
如您所见,我将 TextBlock
(s) 的绑定表示为:Text="{Binding Source={StaticResource Localized}, Path=[A]}"
LocalizedStrings
类型的本地化,它是 App class:
的静态 属性
public class LocalizedStrings : INotifyPropertyChanged
{
private readonly ResourceLoader _resources;
private readonly LocalizationHelper _localizationHelper;
public event PropertyChangedEventHandler PropertyChanged;
public LocalizedStrings()
{
_resources = ResourceLoader.GetForViewIndependentUse();
_localizationHelper = App.LocalizationHelper;
_localizationHelper.OnLocalizationChange += _localizationHelper_OnLocalizationChange;
}
public string this[string key]
{
get
{
return _resources.GetString(key);
}
}
private void _localizationHelper_OnLocalizationChange(object sender, System.EventArgs e)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(string.Empty));
}
}
LocalizationHelper
最有趣的部分是:
public void ChangeLocalizationTo(string cultureCode)
{
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = cultureCode;
OnLocalizationChange?.Invoke(null, new PropertyChangedEventArgs(string.Empty));
}
最后,MainPage按钮的代码:
private void btnChangeLanguage_Click(object sender, RoutedEventArgs e)
{
if (LocalizationHelper.IsCultureItalian(App.LocalizationHelper.GetCurrentLocalizationCode()))
App.LocalizationHelper.ChangeLocalizationTo("en-US");
else App.LocalizationHelper.ChangeLocalizationTo("it-IT");
}
绑定 工作正常,但它们 只是第一次绑定 并且永远不会更新。所以,我启动了应用程序,我看到了字符串(也在设计时),但是当我按下按钮时没有任何反应。似乎 OnLocalizationChange?.Invoke(null, new PropertyChangedEventArgs(string.Empty));
(被调用)不允许应用程序调用 属性 来获取翻译。 (请注意,我使用 string.Empty
作为 属性 名称来通知此 class 中的所有属性都已更改)
"funny" 事实是,使用 WPF 制作的相同示例可以完美运行!
这让我觉得这两个平台的绑定逻辑有一些不同的行为。
我已经尝试放置 Mode=OneWay
绑定,但它不起作用。
(你可以在this GitHub repository看到完整的代码)
修改PrimaryLanguage
后,您需要手动刷新页面。请将以下代码添加到 btnChangeLanguage_Click
方法中。
private void btnChangeLanguage_Click(object sender, RoutedEventArgs e)
{
if (LocalizationHelper.IsCultureItalian(App.LocalizationHelper.GetCurrentLocalizationCode()))
App.LocalizationHelper.ChangeLocalizationTo("en-US");
else App.LocalizationHelper.ChangeLocalizationTo("it-IT");
//refresh current page
Frame.Navigate(this.GetType());
}
更新
I'd thought I could avoid reloading the page by relying on binding
如果您想刷新您的绑定,您可以将页面数据上下文更改为新对象,我们需要重新编写 xaml 绑定,如下所示。
Xaml
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Vertical">
<TextBlock
HorizontalAlignment="Center"
FontSize="20"
Text="{Binding [A]}" />
<TextBlock
HorizontalAlignment="Center"
FontSize="20"
Text="{Binding [B]}" />
<TextBlock
HorizontalAlignment="Center"
FontSize="20"
Text="{Binding [C]}" />
<Button
x:Name="btnChangeLanguage"
Margin="10"
Padding="10"
Click="btnChangeLanguage_Click"
Content="{Binding [Change]}" />
</StackPanel>
代码隐藏
public MainPage()
{
InitializeComponent();
this.DataContext = new LocalizedStrings();
}
private async void btnChangeLanguage_Click(object sender, RoutedEventArgs e)
{
if (LocalizationHelper.IsCultureItalian(App.LocalizationHelper.GetCurrentLocalizationCode()))
App.LocalizationHelper.ChangeLocalizationTo("en-US");
else App.LocalizationHelper.ChangeLocalizationTo("it-IT");
await Task.Delay(100); // used to prepare the resource.
this.DataContext = new LocalizedStrings();
}
我正在尝试实现一个简单的 "press a button to change the App language and all dependent strings" 示例。 (你可以在this GitHub repository看到完整的代码)
在此示例中,我将三个 TextBlock
和一个按钮绑定到我的语言资源:
并且:
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Vertical">
<TextBlock
HorizontalAlignment="Center"
FontSize="20"
Text="{Binding Source={StaticResource Localized}, Path=[A]}" />
<TextBlock
HorizontalAlignment="Center"
FontSize="20"
Text="{Binding Source={StaticResource Localized}, Path=[B]}" />
<TextBlock
HorizontalAlignment="Center"
FontSize="20"
Text="{Binding Source={StaticResource Localized}, Path=[C]}" />
<Button
x:Name="btnChangeLanguage"
Margin="10"
Padding="10"
Click="btnChangeLanguage_Click"
Content="{Binding Source={StaticResource Localized}, Path=[Change]}" />
</StackPanel>
如您所见,我将 TextBlock
(s) 的绑定表示为:Text="{Binding Source={StaticResource Localized}, Path=[A]}"
LocalizedStrings
类型的本地化,它是 App class:
public class LocalizedStrings : INotifyPropertyChanged
{
private readonly ResourceLoader _resources;
private readonly LocalizationHelper _localizationHelper;
public event PropertyChangedEventHandler PropertyChanged;
public LocalizedStrings()
{
_resources = ResourceLoader.GetForViewIndependentUse();
_localizationHelper = App.LocalizationHelper;
_localizationHelper.OnLocalizationChange += _localizationHelper_OnLocalizationChange;
}
public string this[string key]
{
get
{
return _resources.GetString(key);
}
}
private void _localizationHelper_OnLocalizationChange(object sender, System.EventArgs e)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(string.Empty));
}
}
LocalizationHelper
最有趣的部分是:
public void ChangeLocalizationTo(string cultureCode)
{
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = cultureCode;
OnLocalizationChange?.Invoke(null, new PropertyChangedEventArgs(string.Empty));
}
最后,MainPage按钮的代码:
private void btnChangeLanguage_Click(object sender, RoutedEventArgs e)
{
if (LocalizationHelper.IsCultureItalian(App.LocalizationHelper.GetCurrentLocalizationCode()))
App.LocalizationHelper.ChangeLocalizationTo("en-US");
else App.LocalizationHelper.ChangeLocalizationTo("it-IT");
}
绑定 工作正常,但它们 只是第一次绑定 并且永远不会更新。所以,我启动了应用程序,我看到了字符串(也在设计时),但是当我按下按钮时没有任何反应。似乎 OnLocalizationChange?.Invoke(null, new PropertyChangedEventArgs(string.Empty));
(被调用)不允许应用程序调用 属性 来获取翻译。 (请注意,我使用 string.Empty
作为 属性 名称来通知此 class 中的所有属性都已更改)
"funny" 事实是,使用 WPF 制作的相同示例可以完美运行!
这让我觉得这两个平台的绑定逻辑有一些不同的行为。
我已经尝试放置 Mode=OneWay
绑定,但它不起作用。
(你可以在this GitHub repository看到完整的代码)
修改PrimaryLanguage
后,您需要手动刷新页面。请将以下代码添加到 btnChangeLanguage_Click
方法中。
private void btnChangeLanguage_Click(object sender, RoutedEventArgs e)
{
if (LocalizationHelper.IsCultureItalian(App.LocalizationHelper.GetCurrentLocalizationCode()))
App.LocalizationHelper.ChangeLocalizationTo("en-US");
else App.LocalizationHelper.ChangeLocalizationTo("it-IT");
//refresh current page
Frame.Navigate(this.GetType());
}
更新
I'd thought I could avoid reloading the page by relying on binding
如果您想刷新您的绑定,您可以将页面数据上下文更改为新对象,我们需要重新编写 xaml 绑定,如下所示。
Xaml
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Vertical">
<TextBlock
HorizontalAlignment="Center"
FontSize="20"
Text="{Binding [A]}" />
<TextBlock
HorizontalAlignment="Center"
FontSize="20"
Text="{Binding [B]}" />
<TextBlock
HorizontalAlignment="Center"
FontSize="20"
Text="{Binding [C]}" />
<Button
x:Name="btnChangeLanguage"
Margin="10"
Padding="10"
Click="btnChangeLanguage_Click"
Content="{Binding [Change]}" />
</StackPanel>
代码隐藏
public MainPage()
{
InitializeComponent();
this.DataContext = new LocalizedStrings();
}
private async void btnChangeLanguage_Click(object sender, RoutedEventArgs e)
{
if (LocalizationHelper.IsCultureItalian(App.LocalizationHelper.GetCurrentLocalizationCode()))
App.LocalizationHelper.ChangeLocalizationTo("en-US");
else App.LocalizationHelper.ChangeLocalizationTo("it-IT");
await Task.Delay(100); // used to prepare the resource.
this.DataContext = new LocalizedStrings();
}