2009-12-29 3 views
0

Я боролся с получением привязки данных для работы в WPF чуть более недели. Я получил ценную помощь здесь в отношении DataContext, и я получил привязку данных для работы через DependencyProperties. Пока я узнавал о привязке данных, я столкнулся с многочисленными дискуссиями о INotifyPropertyChanged и о том, как это лучше, чем DP во многих отношениях. Я подумал, что сделаю это и попробую.Databinding с INotifyPropertyChanged вместо DependencyProperties

Я использую базовый класс ViewModel для базы Джоша Смита, и моя модель ViewModel получена из него. Тем не менее, у меня есть немного проблем с получением привязки данных для работы, и я надеюсь, что кто-то здесь может сказать мне, где я ошибаюсь.

В моем классе ViewModel у меня есть ObservableCollection<string>. В моей GUI, у меня есть выпадающий, который связан с этой ОС, т.е.

<ComboBox ItemsSource="{Binding PluginNames}" /> 

DataContext Графический интерфейс пользователя имеет значение в ViewModel, т.е.

private ViewModel _vm; 

public GUI() 
{ 
    InitializeComponent(); 
    _vm = new ViewModel(); 
    this.DataContext = _vm; 
} 

и ViewModel имеет OC под названием "PluginNames" :

public class ViewModel 
{ 
    public ObservableCollection<string> PluginNames; // this gets instantiated and added to elsewhere 
} 

Когда GUI загружен, вызывается метод, который создает экземпляр OC и добавляет имена плагинов к нему. После изменения ОС я вызываю RaisePropertyChanged("PluginNames"). Я ожидал, что, поскольку модель привязки данных WPF осведомлена о INotifyPropertyChanged, это все, что мне нужно было сделать, и это «волшебно работает» и обновляет элементы combobox с загружаемыми плагинами ... но это не так.

Может кто-нибудь указать, что я сделал не так? Благодаря!

UPDATE: Я не уверен, почему, но теперь вместо того, чтобы не делать какого-либо явного обновления, он не находит свойство вообще. Я думаю, что я действительно глуп и пропущу важный шаг.

ответ

4

Похоже, вы выставили поле не свойство. Наручники работает только для свойств ... Изменение его:

public class ViewModel 
{ 
    public ObservableCollection<string> PluginNames {get; private set;} 
} 
+1

Не используйте автоматические свойства - они не поднимают событие PropertyChanged. – itowlson

+0

совершенно правый. Argh! В конце концов, я поправимся. :) – Dave

+0

Является ли правильным SO этикетом, чтобы принять самый старый правильный ответ? Я так полагаю. – Dave

6

Когда вы работаете с INotifyPropertyChanged, есть две вещи:

  1. Вы должны будете использовать свойства, а не поля
  2. При установке свойств hte вы всегда должны поднимать событие изменения свойства.

Вы хотите, чтобы переработать это так выглядит как:

private ObservableCollection<string> pluginNames; 
public ObservableCollection<string> PluginNames 
{ 
    get { return pluginNames; } 
    set { 
     this.pluginNames = value; 
     RaisePropertyChanged("PluginNames"); // This should raise the PropertyChanged event - use whatever your VM class does for this 
    } 
} 

Это должно привести все заселить.

+2

На самом деле, вероятно, нет причин иметь сеттер в свойстве, так как это коллекция (и наблюдаемая в ней). –

+0

oh jeez. Это верно! Спасибо. Извините за мою глупость. – Dave

+1

Да, но он специально упомянул, что он настраивал это во время работы, поэтому я включил это. –

Смежные вопросы