ObservableCollection или список данных связываются с ComboBox с использованием MVVM? - PullRequest
0 голосов
/ 29 декабря 2011

У меня есть элементы ObservableCollection. Я хочу связать эти данные со своим комбинированным списком.Как связать данные с помощью comboBox?Я использую шаблон MVVM, поэтому предложите мне связать данные с использованием шаблона MVVM

Я пытаюсь сделать этот код, но не работает должным образом. На моей странице XAML:

<ComboBox x:Name="comobo1" 
          DisplayMemberPath="CardTypeName" 
          SelectedValuePath="CardTypeID" 
          ItemsSource="{Binding Path=combodata}">    
</ComboBox>

В моей ViewModel
(Card моя модель)

 public ObservableCollection<Card> combodata = new ObservableCollection<Card>();
 foreach (var item in App.db.States)
 {
     Card c = new Card(item.StateName, item.StateID);
     combodata.Add(c);
 }

Как связать эти комбоданные с моим comboBox - что я делаю не так?

Ответы [ 7 ]

3 голосов
/ 29 декабря 2011

Сначала: ваш combodata имеет приватный модификатор доступа вместо public . Во-вторых: combodata должно быть свойство , но не поле . И вам лучше добавить реализацию INotifyPropertyChanged в ваш класс.

2 голосов
/ 29 декабря 2011
private ObservableCollection<Card> _combodata;
Public ObservableCollection<Card> comboData
{
   get
   {
      if (_combodata == null)
         _combodata = new ObservableCollection<Card>();
      return _combodata;
   }
   set
   {
       if (value != _combodata)
           _combodata = value;
   }
}


<ComboBox x:Name="comobo1" 
      DisplayMemberPath="CardTypeName" 
      SelectedValuePath="CardTypeID" 
      ItemsSource="{Binding Path=comboData}">    
</ComboBox>

И не забудьте установить свойство DataContext.

2 голосов
/ 29 декабря 2011

Вы должны привязать к общедоступному свойству модели представления, которое должно реализовать INotifyPropertyChanged.

Вот что вы должны сделать:

Представление:

<ComboBox x:Name="comobo1" DisplayMemberPath="CardTypeName" SelectedValuePath="CardTypeID" ItemsSource="{Binding Path=ComboData}" />

ViewModel:

public class MyViewModel : INotifyPropertyChanged
    {
        private ObservableCollection<Card> comboData;

        public event PropertyChangedEventHandler PropertyChanged;

        public ObservableCollection<Card> ComboData
        {
            get
            {
                return this.comboData;
            }

            set
            {
                if (this.comboData != value)
                {
                    this.comboData = value;
                    this.NotifyPropertyChanged("ComboData");
                }
            }
        }

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    }

EDIT : вам также необходимо установить свойство DataContext вашего представления.Простой способ - привязать экземпляр вашей ViewModel к свойству DataContext в коде вашего представления.

1 голос
/ 29 декабря 2011

Мое лучшее предположение, что * ComboBox DataContext не настроен на экземпляр вашей ViewModel

Я часто использую Snoop для отладки проблем DataContext с приложением. Он позволяет вам просматривать дерево визуалов и видеть, что такое DataContext для всех элементов управления.

DataContext - это данные, к которым привязан ваш пользовательский интерфейс. Обычно DataContext устанавливается выше в Visual Tree, например, в объекте Window, хотя в качестве примера следующая строка кода установит DataContext ComboBox в новый экземпляр вашей ViewModel, и тогда ваш ComboBox сможет найти combodata коллекция для привязки к ней.

comobo1.DataContext = new MyViewModel();

Кроме того, измените combodata с Field (без методов получения / установки методов доступа) на Property (см. Ответ Дмитрия для примера)

1 голос
/ 29 декабря 2011

Существуют следующие проблемы с кодом.

1.Вы не можете привязать частное поле или свойство.Это должна быть публичная собственность.

2.Вы предоставили только ItemsSource="{Binding Path=combodata}", но не указали источник.Откуда берутся комбоданные?

ObservableCollection не имеет ничего общего, если только ваши поля со списком не меняются после заполнения.В этом случае List может работать хорошо.

Чтобы заставить его работать, измените ваши комбоданные на публичное свойство как

public ObservableCollection<Card> combodata {get;set;}

, затем

<ComboBox x:Name="comobo1" 
          DisplayMemberPath="CardTypeName" 
          SelectedValuePath="CardTypeID" 
          ItemsSource="{Binding Path=combodata}" ElementName=mainWindow>    
</ComboBox>

, указав ElementNameговорят механизму связывания WPF искать свойство combodata класса mainWindow.

Надеюсь, это поможет.

0 голосов
/ 30 декабря 2011

Правильный ответ:

На странице XAML ":

<CollectionViewSource x:Key="comboBoxCollection" Source="{Binding comboData}"></CollectionViewSource>
  <DataTemplate x:Key="ComboBoxDataTemplate">
            <Grid MinHeight="25">
                <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                  <ComboBox x:Name="comobo1" DisplayMemberPath="CardTypeName"   SelectedValuePath="CardTypeID" ItemsSource="{Binding Source={StaticResource comboBoxCollection }}">
                    </ComboBox>
            </Grid>
         </DataTemplate>

В ViewModel:

 private ObservableCollection<Card> _combodata;

        public ObservableCollection<Card> comboData
        {
            get
            {
                if (_combodata == null)
                    _combodata = new ObservableCollection<Card>();
                return _combodata;
            }
            set
            {
                if (value != _combodata)
                    _combodata = value;
            }
        }

  if (_objCardField.FieldTag == "State") 
                {
                    cards = new Cards();
                    foreach (var item in App.db.States)
                    {
                        Card c = new Card(item.StateName, item.StateID);
                        comboData.Add(c);
                    }
                }
0 голосов
/ 29 декабря 2011

Вам необходимо привязать к публичной собственности. В вашем примере combodata является частной.

...