1

I have this classes

 public class UILanguagesModel : INotifyPropertyChanged
    {
        public UILanguagesModel()
        {
            IList<UILanguage> list = new List<UILanguage>();

            UILanguage english = new UILanguage();
            english.Culture = "en";
            english.SpecCulture = "en-US";
            english.EnglishName = "English";           

            UILanguage spanish = new UILanguage();
            spanish.Culture = "es";
            spanish.SpecCulture = "es-ES";
            spanish.EnglishName = "Spanish";   

            list.Add(english);
            list.Add(spanish);
            _languages = new CollectionView(list);
        }
        private readonly CollectionView _languages;
        private UILanguage _language;

        public CollectionView Languages
        {
            get { return _languages; }
        }

        public UILanguage Language
        {
            get { return _language; }
            set
            {
                if (_language == value) return;
                _language = value;
                OnPropertyChanged("Language");
            }
        }
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }

    public sealed class UILanguage
    {
        public string EnglishName { set; get; }

        public string Culture { set; get; }

        public string SpecCulture { set; get; }
    }

And I need to populate with "EnglisgName" WPF Combobox.

How to do it?

Thank you!


Markup XAML

 <ComboBox Grid.Column="1" Height="23" HorizontalAlignment="Left" Margin="0,1,0,0" 
                  Name="cmbLanguages" VerticalAlignment="Top" Width="207" />
4
  • @ShoaibShaikh Yes Here it is. Commented Jan 18, 2012 at 16:53
  • 1
    Why are you doing multiple language support for your UI in this fashion? Its possible to detect the current system culture. I hate programs that let me select a language that I cannot even read. Commented Jan 18, 2012 at 18:00
  • @Ramhoud. In fact I will use this fashion of localization c-sharpening.blogspot.com/2011/04/… :) So language will depend on system culture by default. Commented Jan 18, 2012 at 18:15
  • @Ramhoud. But anyway I need to give possibility to user to select other language and keep it. Sometimes Chinese folk have to work with Spanish UI under French MS Windows... You know what I mean? Hahahaha Commented Jan 18, 2012 at 18:15

2 Answers 2

3

When binding a ComboBox to a collection of items you would usually define your collection class as an ObservableCollection:

public class UILanguages : ObservableCollection<UILanguage>
{
}

and bind your ComboBox to a CollectionViewSource that uses the ObservableCollection as Source, like declared in the following XAML. CollectonViewSource keeps tracks of the selected item.

<Window x:Class="ComboBoxTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:ComboBoxTest"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:UILanguages x:Key="UILanguages"/>
        <CollectionViewSource x:Key="UILanguagesViewSource" Source="{StaticResource UILanguages}"/>
    </Window.Resources>
    <Grid>
        <ComboBox Grid.Column="1" Height="23" HorizontalAlignment="Left" Margin="0,1,0,0"  
                  Name="cmbLanguages" VerticalAlignment="Top" Width="207"
                  ItemsSource="{Binding Source={StaticResource UILanguagesViewSource}}"/>
    </Grid>
</Window>

Then populate the collection:

UILanguages languages = (UILanguages)Resources["UILanguages"];

languages.Add(
    new UILanguage
    {
        Culture = "en",
        SpecCulture = "en-US",
        EnglishName = "English"
    });

languages.Add(
    new UILanguage
    {
        Culture = "es",
        SpecCulture = "es-ES",
        EnglishName = "Spanish"
    }); 

It is of course also possible to define the ObservableCollection and the CollectionViewSource in code, thus avoiding the XAML resource declarations:

UILanguages languages = new UILanguages();

languages.Add(
    new UILanguage
    {
        Culture = "en",
        SpecCulture = "en-US",
        EnglishName = "English"
    });

languages.Add(
    new UILanguage
    {
        Culture = "es",
        SpecCulture = "es-ES",
        EnglishName = "Spanish"
    });

CollectionViewSource cvs = new CollectionViewSource
{
    Source = languages
};

cmbLanguages.SetBinding(ItemsControl.ItemsSourceProperty, new Binding { Source = cvs });

You may also want to override ToString in your UILanguage class to display something useful:

public sealed class UILanguage
{
    public string EnglishName { set; get; }

    public string Culture { set; get; }

    public string SpecCulture { set; get; }

    public override string ToString()
    {
        return EnglishName;
    }
} 
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your help! I get some error using you snippet. Error 1 ''local' is an undeclared prefix. Line 8, position 10.' XML is not valid. D:\....
I've completed the XAML. local is simply the XAML namespace declaration of the project's namespace, ComboBoxTest here.
Thank you very much! Your solution completely perfect for me. It works fine!
1

If in the constructor of the View (the C# file associated with your XAML), you set:

this.DataContext = new UILanguagesModel ();

Then it's as simple as a Binding:

<ComboBox Grid.Column="1" Height="23" HorizontalAlignment="Left" Margin="0,1,0,0" 
                  Name="cmbLanguages" VerticalAlignment="Top" Width="207" 
                  ItemsSource="{Binding Languages}"/>

Then you're probably going to want the selected value of your ComboBox to be in your Language property, in which case the binding becomes:

<ComboBox Grid.Column="1" Height="23" HorizontalAlignment="Left" Margin="0,1,0,0" 
                      Name="cmbLanguages" VerticalAlignment="Top" Width="207" 
                      ItemsSource="{Binding Languages}"
                      SelectedValue="{Binding Language}"/>

EDIT: You're probably going to have to declare your Languages collection as an ObservableCollection

2 Comments

Sorry I did as u said but it doesn't populate combobox.
I'm not sure I understand what you just meant. It works with the code I provided?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.