问题
I am working on adding localization to an application that uses .NET 3.5. The application is using MVVM pattern and a command to change the culture. Everything is working well except that the DatePicker control does not change language until after I click on it. At this point, the selected date text will change properly. The dropdown calendar in the control also will not change language until I move the month either forward or backwards once.
How can I force the control to refresh with the proper language as soon as the command is run to change culture?
I have tried several things with no success including:
- DatePickerControl.InvalidateVisual()
- DatePickerControl.UpdateLayout()
- Firing NotifyPropertyChanged on the CultureChanged event for SelectedDate in VM
- DatePickerControl.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate)
App.xaml.cs
protected override void OnStartup(StartupEventArgs e)
{
ApplicationCulture.Instance.CultureChanged += Instance_CultureChanged;
base.OnStartup(e);
}
private void Instance_CultureChanged(object sender, CultureChangedEventArgs e)
{
System.Threading.Thread.CurrentThread.CurrentUICulture = e.Culture;
System.Threading.Thread.CurrentThread.CurrentCulture = e.Culture;
}
View
<UserControl x:Class="ManageAppointmentsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:toolkit="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit">
<StackPanel>
<TextBlock Margin="5" FontSize="15" Text="{Binding LocalizedResources.Resource.Date}" />
<toolkit:DatePicker SelectedDate="{Binding SelectedDate}" SelectedDateFormat="Long" FontSize="15" VerticalContentAlignment="Center"
DisplayDateStart="{Binding StartDate}" CalendarStyle="{StaticResource CalendarStyle}" x:Name="DatePickerControl" />
</StackPanel>
</UserControl>
ViewModel command
ChangeLanguageCommand = new SimpleCommand
{
ExecuteDelegate = x =>
{
var newCulture = x == null
? "en-US"
: x.ToString();
ApplicationCulture.Instance.CurrentCulture =
new CultureInfo(newCulture);
}
};
ApplicationCulture
public class ApplicationCulture : INotifyCultureChanged
{
private ApplicationCulture() { }
private static ApplicationCulture _instance;
public static ApplicationCulture Instance
{
get
{
if (_instance == null)
_instance = new ApplicationCulture();
return _instance;
}
}
private CultureInfo _currentCulture = CultureInfo.InvariantCulture;
public CultureInfo CurrentCulture
{
get { return _currentCulture; }
set
{
if (!CultureInfo.Equals(value, _currentCulture))
{
_currentCulture = value;
NotifyCultureChanged(value);
}
}
}
public event EventHandler<CultureChangedEventArgs> CultureChanged;
private void NotifyCultureChanged(CultureInfo culture)
{
if (CultureChanged != null)
CultureChanged(this, new CultureChangedEventArgs(culture));
}
}
回答1:
In this case, the solution might be in changing the user interaction pattern. In a paged application, I'd switch to a separate page in order to select the language, and switch back to the original page when it is changed. So, the page would be initialized anew, including all localized but otherwise static resources. In a non-paged application, you could e.g. use a dialog to change the UI language, while you close and reopen the main window.
In both cases, the trick would be to preserve the ViewModel instance from before and after changing the language, so that the view state and the entered data are preserved while the localized resources are reloaded.
来源:https://stackoverflow.com/questions/14779981/how-to-force-wpf-toolkit-datepicker-to-refresh-in-ui-after-culture-change