2017-01-24 4 views
1

У меня есть поле со списком, связанное с объектом из модели, созданной внутри моей модели представления. OnPropertyChange обрабатывается внутри класса Notifier, который наследуется от INotifyPropertyChange. Опрос модели представления выполняет метод с уровня доступа к данным и возвращает наблюдаемый список в модель представления. Затем он передается в конструктор, который строит объект, который я хочу связать с полем со списком. Объект имеет два свойства. 1) Наблюдаемый список возможных выборов и 2) строка, представляющая текущий выбранный элемент.WPF Combo box не вызывает метод setter, когда элемент изменен

В этом проблема. Комбинированный номер успешно связан и заполняется списком. Тем не менее, как правило, он не вызывает метод setter при изменении элемента. Мне нужна эта функциональность, поэтому я могу продолжить логику приложения после выбора элемента. Отладка подтверждает, что никакой сеттер не вызван, только get. Однако сеттер называет модель, но имеет смысл. Я уверен, что у меня что-то отсутствует, и я открыт для предложений по лучшему способу сделать это.

Модель

public class WellListGroup : Notifier 
    { 

     private ObservableCollection<string> _headers; 

     public ObservableCollection<string> headers 
     { 
      get { return _headers; } 
      set { _headers = value; OnPropertyChanged("headers"); } 
     } 

     private string _selected; 

     public string selected 
     { 
      get { return this._selected;} 
      set { this._selected = value; OnPropertyChanged("selected");} 
     } 

    } 

Notifier

public class Notifier : INotifyPropertyChanged 
    { 

     public event PropertyChangedEventHandler PropertyChanged; 

     protected void OnPropertyChanged(string propertyName) 
     { 
      if(PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 

вид Модель

public class MainViewModel : Notifier 
{ 
    //data access layer 
    public static getWells gw = new getWells(); 

    //set combo box 
    public static ObservableCollection<string> headers = gw.getHeaders(); 
    private WellListGroup _wlg = new WellListGroup {headers = headers, selected = headers[0]}; 

    public WellListGroup wlg 
    { 
     get { 
      return _wlg; 
     } 
     set { 
       _wlg = value; 
       OnPropertyChanged("wlg"); 
       OnChange()// do stuff!!! 

      } 
    } 

Посмотреть

<ComboBox x:Name="groupComboBox" 
      DockPanel.Dock="Top" 
      ItemsSource = "{Binding Path = wlg.headers}" 
      SelectedItem="{Binding Path = wlg.selected, Mode=TwoWay}"> 
</ComboBox> 

EDIT - Переработан ViewModel подписаться на события на объекте

public class MainViewModel : Notifier 
{ 
    //data access layer 
    public static getWells gw = new getWells(); 

    //set combo box 
    public static List<string> headers = gw.getHeaders(); 


    private WellListGroup _wlg = new WellListGroup {headers = headers, selected = headers[0]}; 


    public WellListGroup wlg 
    { 
     get { 
      return _wlg; 
     } 
     set { 


       _wlg = value; 
       OnPropertyChanged("wlg"); 
       OnChange(_wlg.selected);// do stuff!!! 

      } 

    } 

    public MainViewModel() 
    { 
     // Move this into the constructor to avoid any race conditions 
     _wlg = new WellListGroup {headers = headers, selected = headers[0]}; 

     // Subscribe to the property change even for WLG 
     _wlg.PropertyChanged += (sender, args) => 
     { 
      if (args.PropertyName == "selected") { 

      } 
       OnChange(_wlg.selected);// do stuff!!! 
     }; 
    } 
+0

'wlg' на самом деле не устанавливается здесь' wlg.selected'. Вы можете переместить его на 'OnChanged()' на выбранную функцию набора или захватить событие SelectionChanged в выпадающем списке. – JaredStroeb

+0

Хорошо, я понимаю, что вы здесь говорите. Есть ли способ обрабатывать любой из них из модели просмотра? – LCaraway

+0

Я так не думаю, что выбрано свойство combobox - это то, что меняется, а не выбранное свойство вашей модели. – Bloodday

ответ

1

Ситуация такова, что отраженная сеттер свойство в_wlg класс и не сеттер класс _wlg на виртуальной машине. Ограниченный предмет не подходит к верхнему уровню, но нижнее свойство, как указано.

Либо введите командную систему, чтобы запустить код OnChange()// do stuff!!!, либо подписаться на событие класса _wlgINotifyProptertyChanged и вызвать метод, о котором вы упомянули.


Есть в любом случае, чтобы справиться с любым из тех, внутри модели представления?

Да, подписаться на экземпляр класса WellListGroup свойств измененного события и искать selected или других, чтобы сообщить об изменениях.

public MainViewModel() 
{ 
    // Move this into the constructor to avoid any race conditions 
    _wlg = new WellListGroup {headers = headers, selected = headers[0]}; 

    // Subscribe to the property change even for WLG 
    _wlg.PropertyChanged += (sender, args) => 
      { 
       if (args.PropertyName == 'selected') 
        OnChange()// do stuff!!! 
      }; 
} 

Следует отметить, что остается неясным, если вам действительно нужно для хранения строк в ObservableCollection. Эта коллекция имеет собственную реализацию уведомлений о событиях для добавления и удаления элементов в коллекции.

Если VM нуждается в этой конкретной информации об изменении, вам необходимо будет подписаться на события (ы) ObservableCollection для таких операций вместо /, а также вышеупомянутый выше пример.

Если вам не нужны эти уведомления, удерживание строк в ObservableCollection не требуется, и вы можете изменить его на List<string>.

+0

Я делаю это. Мне специально не нужна наблюдаемая коллекция и она ее перечислила в список . Наблюдаемая коллекция была более ранней попыткой заставить меня работать. Не могли бы вы уточнить, где включить вышеупомянутое решение. Я отредактирую свой вопрос, чтобы показать, что я изменил, что имело смысл для меня. Хотя я, конечно, все еще новичок во всем этом, поэтому, пожалуйста, объясните, где/Почему я ошибаюсь. – LCaraway

+0

Я вижу, что вы поместили свой код внутри метода с именем модели представления, можете ли вы объяснить размещение этого и как оно относится к модели конструктора/представления? – LCaraway

+0

@LCaraway код - это назначение события, которое вместо другого именованного метода использует встроенный анонимный делегат, использующий лямбда-нотацию. Вы также можете просто создать метод с той же сигнатурой в коде, и он будет работать нормально. – OmegaMan

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