Question

I am trying to set up a multi-language application, so when the user changes the display language all the texts in all the open windows change automatically. I am having issues through with binding combo-box control. The binding needs to be done in code-behind as I have dynamic content coming from a database, and sometimes I even have to create additional combo-boxes at runtime. Also I do not want to keep the translations in the database because I do not want to query the database every time a user is changing the display language. What I did until now:

in xaml:

<ComboBox x:Name="cmb"/>

and in C#:

    public class MyCmbItem
    {
        public int Index { get; set; }
        public string Text { get; set; }
    }

    private ObservableCollection<MyCmbItem> LoadText() 
    {
        ObservableCollection<MyCmbItem> _result = new ObservableCollection<MyCmbItem>();
        foreach (var _item in _list)
        {
            //the list is coming from a database read
            _result.Add(new MyCmbItem { Index = _item.Value, Text = _res_man_global.GetString(_item.KeyText, _culture) });
        }
        return _result;
    }


    public ObservableCollection<MyCmbItem> MyTexts
    {
        get { return LoadText(); }
        set {} //I do not have to add/remove items at runtime so for now I leave this empty
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        ...
        LoadList(); //this adds values in _list
        cmb.ItemsSource = MyTexts; //this populates the combo-box

Here I got stuck and I do not know how to determine the combo-box to refresh the displayed texts. The method must achieve that if I have several windows opened each containing a random number of combo-boxes, when I change the current language all the combo-boxes in all the windows will refresh the displayed list, without affecting other values inside (like the selected item). Does anybody know how this can be done?

Many thanks.

Was it helpful?

Solution

For your xaml UI, the INotifyPropertyChanged interface indicates updates of the viewmodel. You can extend your class like this:

public class MyCmbItem : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged(string APropertyName)
    {
        var property_changed = PropertyChanged;
        if (property_changed != null)
        {
            property_changed(this, new PropertyChangedEventArgs(APropertyName));
        }
    }  

    private string _Text;
    private string _KeyText;

    public int Index { get; set; }


      public string Text
      {
          get { return _Text;}

          set { 
              if (_Text != value)
              {
                  _Text = value;
                  NotifyPropertyChanged("Text");

              }
          }
      } 

    public MyCmbItem(string key_text, int index)
    {
        Index = index;
        _KeyText = key_text;

        RefreshText();

        _res_man_global.LanguageChanged += () => RefreshText();
    }

    public void RefreshText()
    {
        Text = _res_man_global.GetString(_KeyText, _culture);
    }
}

Your view can simply bind to the Text-property as following:

  <DataTemplate DataType="{x:Type local:MyCmbItem}">
            <TextBlock Text="{Binding Path=Text}"/>
        </DataTemplate>

Note: I assumed that your language class is global and has some kind of language-changed notification event.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top