WPF - 在异步任务的回调中更改 UI 文化
WPF - Change UI culture in callback of asynchrone task
在我的应用程序中,用户可以切换语言。在应用更改之前,会进行检查。
在完全同步的情况下,这项工作正常。
现在,检查是异步的,UI 线程集 CultureInfo.CurrentUICulture
上的回调。
但是在回调结束时,CultureInfo.CurrentUICulture
被回滚。看这个例子:
MainWindow.xaml :
<StackPanel>
<ComboBox SelectionChanged="ComboBox_Selected">
<ComboBoxItem>en-US</ComboBoxItem>
<ComboBoxItem>en-GB</ComboBoxItem>
<ComboBoxItem>fr-FR</ComboBoxItem>
</ComboBox>
<Button Click="Button_Click">Display</Button>
</StackPanel>
MainWindow.xaml.cs :
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ComboBox_Selected(object sender, RoutedEventArgs e)
{
Debug.WriteLine($"A - {Thread.CurrentThread.ManagedThreadId} - {Thread.CurrentThread.IsBackground}");
var to = ((ComboBoxItem)((ComboBox)sender).SelectedItem).Content as string;
Task.Delay(TimeSpan.FromSeconds(1)).ContinueWith(
t => SetCurrentCulture(to),
TaskScheduler.FromCurrentSynchronizationContext()
);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(CultureInfo.CurrentCulture.Name);
}
private static void SetCurrentCulture(string to)
{
Debug.WriteLine($"B - {Thread.CurrentThread.ManagedThreadId} - {Thread.CurrentThread.IsBackground}");
var culture = new CultureInfo(to);
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture;
}
}
你能解释一下为什么吗?
如何解决这个问题?
你能解释一下为什么吗?
来自docs:
For apps that target the .NET Framework 4.6 or later versions, culture is part of an asynchronous operation's context. In other words, starting with apps that target the .NET Framework 4.6, asynchronous operations by default inherit the values of the CurrentCulture
and CurrentUICulture
properties of the thread from which they are launched.
如何解决?
将以下开关添加到您的 App.config
文件以切换回 .NET Framework 4.5.2 中的行为:
<runtime>
<AppContextSwitchOverrides value="Switch.System.Globalization.NoAsyncCurrentCulture=true" />
</runtime>
在我的应用程序中,用户可以切换语言。在应用更改之前,会进行检查。 在完全同步的情况下,这项工作正常。
现在,检查是异步的,UI 线程集 CultureInfo.CurrentUICulture
上的回调。
但是在回调结束时,CultureInfo.CurrentUICulture
被回滚。看这个例子:
MainWindow.xaml :
<StackPanel>
<ComboBox SelectionChanged="ComboBox_Selected">
<ComboBoxItem>en-US</ComboBoxItem>
<ComboBoxItem>en-GB</ComboBoxItem>
<ComboBoxItem>fr-FR</ComboBoxItem>
</ComboBox>
<Button Click="Button_Click">Display</Button>
</StackPanel>
MainWindow.xaml.cs :
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ComboBox_Selected(object sender, RoutedEventArgs e)
{
Debug.WriteLine($"A - {Thread.CurrentThread.ManagedThreadId} - {Thread.CurrentThread.IsBackground}");
var to = ((ComboBoxItem)((ComboBox)sender).SelectedItem).Content as string;
Task.Delay(TimeSpan.FromSeconds(1)).ContinueWith(
t => SetCurrentCulture(to),
TaskScheduler.FromCurrentSynchronizationContext()
);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(CultureInfo.CurrentCulture.Name);
}
private static void SetCurrentCulture(string to)
{
Debug.WriteLine($"B - {Thread.CurrentThread.ManagedThreadId} - {Thread.CurrentThread.IsBackground}");
var culture = new CultureInfo(to);
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture;
}
}
你能解释一下为什么吗? 如何解决这个问题?
你能解释一下为什么吗?
来自docs:
For apps that target the .NET Framework 4.6 or later versions, culture is part of an asynchronous operation's context. In other words, starting with apps that target the .NET Framework 4.6, asynchronous operations by default inherit the values of the
CurrentCulture
andCurrentUICulture
properties of the thread from which they are launched.
如何解决?
将以下开关添加到您的 App.config
文件以切换回 .NET Framework 4.5.2 中的行为:
<runtime>
<AppContextSwitchOverrides value="Switch.System.Globalization.NoAsyncCurrentCulture=true" />
</runtime>