Search code examples
c#xamlmaui

Using localization in .NET MAUI picker


`I created resx files in my .NET MAUI project to use different languages. I want to use them within a picker. I followed the approach below in XAML, but it didn't work. What should I do?

<Picker Title="{x:Static resx:AppResources.PickerTitle}">
    <Picker.ItemsSource>
        <x:Array Type="{x:Type x:String}">
            <x:String>{x:Static resx:AppResources.Option1}</x:String>
            <x:String>{x:Static resx:AppResources.Option2}</x:String>
            <x:String>{x:Static resx:AppResources.Option3}</x:String>
        </x:Array>
    </Picker.ItemsSource>
</Picker>

`


Solution

  • Her is a possible solution that uses Behaviours and WeakReferenceMessenger. Not all that pretty but has possibilities.

    Requirement is that you have made the resources for the different language you want.

    Let us start with the implementation. We got a picker and a radio buttons group. The picker got a Behavior that is going to do all the magic.

    <Picker x:Name="MyPicker" Title="{x:Static localization:AppResources.PickerTitle}">
       <Picker.Behaviors>
          <local:LocalizedPickerBehavior />
       </Picker.Behaviors>
    </Picker>
    <local:RadioButtonGroup />
    

    We create the behaviour. Here we initialize the Messenger that will tell the Behaviour that we have changed language.

    public class LocalizedPickerBehavior : Behavior<Picker>
    {
        protected override void OnAttachedTo(Picker picker)
        {
            base.OnAttachedTo(picker);
    
            // Set the ItemsSource of the Picker
            SetItemsSource(picker);
    
    
            // Listen for the LanguageChanged notification
            WeakReferenceMessenger.Default.Register<LocalizedPickerBehaviorMessage>(this, (recipient, message) => {
                var culture = new CultureInfo(message.Value);
                CultureInfo.CurrentUICulture = culture;
                SetItemsSource(picker);
            });
        }
    
        private void SetItemsSource(Picker picker)
        {
            var option1 = AppResources.Option1;
            var option2 = AppResources.Option2;
            var option3 = AppResources.Option3;
    
            picker.Title = AppResources.PickerTitle;
            var currentIndex = picker.SelectedIndex;
            picker.ItemsSource = new List<string> { option1, option2, option3 };
            picker.SelectedIndex = currentIndex;
        }
    
        protected override void OnDetachingFrom(Picker picker)
        {
            base.OnDetachingFrom(picker);
    
            picker.ItemsSource = null;
    
            WeakReferenceMessenger.Default.Unregister<LocalizedPickerBehavior>(this);
        }
    }
    

    For the messenger we need a message that we send with the language we want to change to.

    public class LocalizedPickerBehaviorMessage : ValueChangedMessage<string>
    {
        public LocalizedPickerBehaviorMessage(string lang) : base(lang)
        {
        }
    }
    

    And we finnish of with a simple radio button that sends the message to our behaviour.

    public class RadioButtonGroup : StackLayout
    {
        public RadioButton RadioButton1 { get; private set; }
        public RadioButton RadioButton2 { get; private set; }
    
        public RadioButtonGroup()
        {
            Orientation = StackOrientation.Horizontal;
            RadioButton1 = new RadioButton { Content = "English" };
            RadioButton2 = new RadioButton { Content = "Swedish" };
    
            RadioButton1.CheckedChanged += OnRadioButtonCheckedChanged;
            RadioButton2.CheckedChanged += OnRadioButtonCheckedChanged;
    
            Children.Add(RadioButton1);
            Children.Add(RadioButton2);
    
            RadioButton1.IsChecked = true;
        }
    
        private void OnRadioButtonCheckedChanged(object sender, CheckedChangedEventArgs e)
        {
            var radioButton = (RadioButton)sender;
    
            if (radioButton == RadioButton1 && RadioButton1.IsChecked)
            {
                RadioButton2.IsChecked = false;
                WeakReferenceMessenger.Default.Send(new LocalizedPickerBehaviorMessage("en"));
            }
            else if (radioButton == RadioButton2 && RadioButton2.IsChecked)
            {
                RadioButton1.IsChecked = false;
                WeakReferenceMessenger.Default.Send(new LocalizedPickerBehaviorMessage("sv"));
            }
        }
    }
    

    Here is a visual:

    enter image description here