简体   繁体   中英

How to force WPF Toolkit DatePicker to refresh in UI after culture change?

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));
    }
}

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 eg 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM