@bagos

Как заставить обновляться ListBox с помощью INotifyPropertyChanged?

class MyClassA
{
        private ObservableCollection<AnotherClass> _listCode;
        public ObservableCollection<AnotherClass> ListCode
        {
            get
            {
                return _listCode;
            }
            set
            {
                if (value == _listCode) return;
                _listCode= value;
                OnPropertyChanged("ListCode");
            }
        }

     public void GetList()
     {
           ListCode = ...
     }

        public event PropertyChangedEventHandler PropertyChanged;

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


В XAML:
<ListBox ItemsSource="{Binding Path=ListCode}" ItemTemplateSelector="{StaticResource ListTemplateSelector}" />


В застраничном классе связан с MyClass через DataContext.

Когда выполняется GetList в конструкторе класса, то ListBox отображает значения, в случае когда вызываю GetList после того как обновил ListCode , ListBox не обновляется, хотя в дебаггере вижу что ListCode содержит новый элемент.
OnPropertyChanged не отрабатывает, почему?
UPD Причем если добавить элемент в ListCode и вызвать GetList , то в этом случае новый элемент отобразится в ListBox. Не работает в случае если GetList вызывать из другого класса...
  • Вопрос задан
  • 1265 просмотров
Решения вопроса 3
@vitvov
1 вариант: Ваш класс должен наследовать INotifyPropertyChanged, только тогда он будет работать.
2 вариант: ObservableCollection реализует INotifyPropertyChanged сам, поэтому, чтоб пользоватся им, ваш код должен выглядеть примерно так:
class MyClassA
{
      public ObservableCollection<AnotherClass> ListCode { get; private set; };
        
      public MyClassA()
      {
            // ...
            ListCode = new ObservableCollection<AnotherClass>();
      }

      public void GetList()
      {
            ListCode.Clear();
            // ...
            ListCode.Add(new AnotherClass());
      }
}
Ответ написан
Комментировать
@bagos Автор вопроса
Благодарю за ответы, поподробнее распишу:
class MyClassA
{

public MyClassA {
GetList();
}
        private ObservableCollection<AnotherClass> _listCode;
        public ObservableCollection<AnotherClass> ListCode
        {
            get
            {
                return _listCode;
            }
            set
            {
                if (value == _listCode) return;
                _listCode= value;
                OnPropertyChanged("ListCode");
            }
        }

     public void GetList()
     {
           ListCode = (берется из базы)
     }

        public event PropertyChangedEventHandler PropertyChanged;

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

При старте приложение подгружает ListCode и отображает в listbox'e

в cs xaml:

public static MyClassA MyClassA;
        public MainProgram()
        {
            InitializeComponent();
           <b> MyClassA = new MyClassA ();</b>
            DataContext = MyClassA;
        }


Есть другой класс ClassB - тоже модель, там отрабатывает метод и должен вызвать GetList заново, чтобы отобразить по новой список в listbox. вызов выглядит так
new MyClassA().GetList();
Ответ написан
Комментировать
hePPer
@hePPer
у вас неверная стратегия обновления данных.
Листбокс подписывается на событие не INotifyPropertyChanged, а на INotifyCollectionChanged.
Затем - вначале вы создали ListCode, на который забиндился listbox - все у вас хорошо.
Но, тут вы вызвали метод GetList(), после чего из ListCode пропала ссылка на старый ObservableCollection, и появилась на новый, который уже не связан с listbox. Поэтому в списке вы видите что данные обновились, но т.к. лисбокс остался привязан к старой коллекции, то обновлений он не увидел.

поидее чтобы заработало можно сделать так, хотя будет не оптимально если данных много

public void GetList()
{
var listFromDB= (берется из базы)

ListCode.Clear();
foreach(var item in listFromDB)
ListCode.Add(item);
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы