简体   繁体   中英

CultureInfo.ClearCachedData is not working properly in .net 4.6 and older for WPF only

Consider the following simple WPF application:

XAML (MainWindow):

<StackPanel>
    <TextBlock x:Name="Old"/>
    <TextBlock x:Name="New"/>
</StackPanel>

Codebehind:

  public MainWindow()
        {
            InitializeComponent();
            SystemEvents.UserPreferenceChanged += (sender, args) =>
            {
                Old.Text = $"Old culture name {CultureInfo.CurrentCulture.Name}";
                CultureInfo.CurrentCulture.ClearCachedData();
                New.Text = $"New culture name {CultureInfo.CurrentCulture.Name}";
            };
        }

Each time the user changes their regional settings it will print to Old TextBlock the old culture's name and, after calling ClearCachedData , the new culture's name will be set on New TextBlock. This is the window where I change these settings in Clock and Region section within Control Panel:

在此处输入图片说明

Now, if you build targeting 4.5.2 or less, it will work as expected and you will receive, after actually changing the setting, an output similar to this:

在此处输入图片说明

Now, build targeting 4.6 or later versions, you get something like this:

在此处输入图片说明

If you are targeting 4.6 or later, no matter how many times you change the number format region, no matter how many times you call ClearCachedData , CurrentCulture will not change...

But wait! Things get weirder... If you put above code into a Console App (using Console.WriteLine instead of course), it works not depending in which framework you chose (4.5.2, 4.6, anything..), strange isn't it? That is why I wrote "WPF only" in the title.. but I do not know for sure if this happens in any other platform other than WPF

There is still another crazy thing in this tale, since I have been playing around with this issue since yesterday, I found a trikcy way to make WPF or Console apps, targeting 4.5.2 or below, working wrong, just as the one targeting 4.6 and older. Simply setting CultureInfo.DefaultThreadCurrentCulture to anything different from null will break things apart.

public MainWindow()
{
    InitializeComponent();

    CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CurrentCulture;

    SystemEvents.UserPreferenceChanged += (sender, args) =>
    {
        Old.Text = $"Old culture name {CultureInfo.CurrentCulture.Name}";
        CultureInfo.CurrentCulture.ClearCachedData();
        New.Text = $"New culture name {CultureInfo.CurrentCulture.Name}";
    };
}

The above code will behave as if it were targeting 4.6. So, what I thought was that WPF targeting 4.6 was setting CultureInfo.DefaultThreadCurrentCulture in some way, but after testing this theory I am really stuck, because it is null by default, event in 4.6 and older...

So, is this a bug in WPF and/or .NET 4.6? I have not been able to find this breaking change reported.

Please, anything that shed some light on this will be appreciated. Also, if this is a bug and anyone know where could I report it, please tell me.

Note: I tag this question with C# as it is the language I am using, although I consider this issue is language independent.

For those visitors from the future and beyond who may will be having the same issue. I found a sort of workaround:

    public MainWindow()
    {
        InitializeComponent();

        CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CurrentCulture;

        SystemEvents.UserPreferenceChanged += (sender, args) =>
        {
            Old.Text = $"Old culture name {CultureInfo.CurrentCulture.Name}";
            CultureInfo.CurrentCulture.ClearCachedData();
            CultureInfo.CurrentCulture = new Thread(() => { }).CurrentCulture;
            New.Text = $"New culture name {CultureInfo.CurrentCulture.Name}";
        };
    }

The above code will work in both building options: 4.5.2 and earlier, or 4.6 and later. Notice that the call to ClearCachedData is still a must. We create a new thread instance and we manually update our CurrentCulture to that of the new thread.

Happy coding!

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