Search code examples
wpf.net-coremultilingualresx.net-core-3.1

Content of button is not updated after changing the CurrentUICulture


According to this tutorial, I try to implement the multilingual system to my WPF .NET Core 3.1 application. Everything works fine if I change the property Title of Window element directly, application reads from the corrent resource file, which is is defined by changing the CurrentUICulture.

Here is a code of such a change:

private void BtnChangeLanguageToCsCz_Click(object sender, RoutedEventArgs e)
{
    System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("cs-CZ");
}

private void BtnChangeLanguageToEnUs_Click(object sender, RoutedEventArgs e)
{
    System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
}

However after I click any of these buttons, their content remains unupdated. I feel like I need to call some UI update function or anything like this but can't find anything related so far.

Here is how do I bind the Content property of the Button:

<Button x:Name="BtnInstall" Content="{x:Static p:Resource.ButtonInstall}" HorizontalAlignment="Center" Margin="0,324,0,0" VerticalAlignment="Top" Height="50" Width="200" Click="BtnInstall_Click"/>

Resource files have their modifiers set to public and here are the names:

enter image description here

What should I do to make it update itself?


Solution

  • A found a solution based on this tutorial, and rather than using the thread's culture or resource.resx files, it uses XAML resource dictionaries.

    This can be changed for your case, however, I did this for my MainWindow.xaml:

    • I created two resource dictionaries called 'MainWindow.en-GB.xaml' and 'MainWindow.cs-CZ.xaml', in a folder named /Resources.
    • I then set the build action to Content and the Copy to Output Directory to Copy if newer.
    • Once I created the resource dictionaries, I created an example resource called Text:
    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:sys="clr-namespace:System;assembly=mscorlib">
            <sys:String x:Key="Text">Hello</sys:String>
    </ResourceDictionary>
    
    • Then in my MainWindow.xaml, I added the following code:
    <Window.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="Resources/MainWindow.en-GB.xaml"></ResourceDictionary>
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </Window.Resources>
    
    • Followed by, setting the button's content to the resource Text:
    <Button x:Name="BtnInstall" 
        Content="{DynamicResource ResourceKey=Text}" 
        HorizontalAlignment="Center" 
        Margin="0,324,0,0" 
        VerticalAlignment="Top" 
        Height="50" 
        Width="200" 
        Click="BtnInstall_Click" />
    
    • Finally, by using the LocUtil from the linked tutorial, calling the LocUtil.SwitchLanguage method, I could change between the two:
    private void BtnChangeLanguageToEnUs_Click(object sender, RoutedEventArgs e)
    {
        LocUtil.SwitchLanguage(this, "en-US");
    }