Как заполнить WPF Combobox кодом с помощью пользовательского класса? - PullRequest
1 голос
/ 18 января 2012

У меня есть эти классы

 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; }
    }

И мне нужно заполнить с помощью "EnglisgName" WPF Combobox.

Как это сделать?

Спасибо!


Разметка XAML

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

Ответы [ 2 ]

3 голосов
/ 18 января 2012

При связывании ComboBox с коллекцией элементов вы обычно определяете класс коллекции как ObservableCollection:

public class UILanguages : ObservableCollection<UILanguage>
{
}

и привяжите ваш ComboBox к CollectionViewSource, который использует ObservableCollection в качестве источника, как объявлено в следующем XAML. CollectonViewSource отслеживает выбранный элемент.

<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>

Затем заполните коллекцию:

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"
    }); 

Конечно, также возможно определить ObservableCollection и CollectionViewSource в коде, что позволяет избежать объявлений ресурсов XAML:

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 });

Вы также можете переопределить ToString в своем классе UILanguage, чтобы отобразить что-то полезное:

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;
    }
} 
1 голос
/ 18 января 2012

Если в конструкторе View (файл C #, связанный с вашим XAML), вы задаете:

this.DataContext = new UILanguagesModel ();

Тогда это так просто, как Binding:

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

Тогдавы, вероятно, захотите, чтобы выбранное значение вашего ComboBox было в вашем свойстве Language, и в этом случае привязка становится такой:

<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 'вероятно, вам придется объявить вашу коллекцию Languages как ObservableCollection

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...