INotifyCollectionChanged не обновляет пользовательский интерфейс

У меня есть класс, как показано ниже. Все функции я убрал для краткости

public class PersonCollection:IList<Person>
{}

Теперь у меня есть еще один класс Model, как показано ниже. AddValueCommand — это класс, производный от ICommand, который я снова опускаю.

public class DataContextClass:INotifyCollectionChanged
{
    private PersonCollection personCollection = PersonCollection.GetInstance();

    public IList<Person> ListOfPerson
    {
        get 
        {
            return personCollection;
        }            
    }

    public void AddPerson(Person person)
    {
        personCollection.Add(person);
        OnCollectionChanged(NotifyCollectionChangedAction.Reset);
    }


    public event NotifyCollectionChangedEventHandler CollectionChanged = delegate { };
    public void OnCollectionChanged(NotifyCollectionChangedAction action)
    {
        if (CollectionChanged != null)
        {
            CollectionChanged(this, new NotifyCollectionChangedEventArgs(action));
        }
    }       

    ICommand addValueCommand;

    public ICommand AddValueCommand
    {
        get
        {
            if (addValueCommand == null)
            {
                addValueCommand = new AddValueCommand(p => this.AddPerson(new Person { Name = "Ashish"}));
            }
            return addValueCommand;               
        }
    }
}

В главном окне я привязываю свой пользовательский интерфейс к модели, как показано ниже.

 DataContextClass contextclass = new DataContextClass();           
 this.DataContext = new DataContextClass();

И мой пользовательский интерфейс выглядит так, как показано ниже.

<ListBox Margin="5,39,308,113" ItemsSource="{Binding Path=ListOfPerson}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBox Height="20" Text="{Binding Path=Name}"></TextBox>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <Button Content="Button"  HorizontalAlignment="Left" Command="{Binding Path=AddValueCommand}" Margin="233,39,0,73" />

Мой список не обновляется новым значением при нажатии кнопки. Чего мне здесь не хватает.


person Vikram    schedule 30.04.2013    source источник


Ответы (2)


INotifyCollectionChanged должен быть реализован классом коллекции. Не по классу, содержащему коллекцию.
Вам нужно удалить INotifyPropertyChanged из DataContextClass и добавить его в PersonCollection.

person Daniel Hilgarth    schedule 30.04.2013
comment
Большое спасибо за ответы, но здесь у меня есть сомнения, предположим, что если я не хочу менять свою PersonCollection, как я могу добиться этого, только сделав изменение в DataContextClass - person Vikram; 30.04.2013
comment
@Викрам: Ты не можешь. Механизм WPF ищет этот интерфейс в свойстве, привязанном к ItemsSource. Он не ищет этот интерфейс в контексте данных. - person Daniel Hilgarth; 30.04.2013

Вместо использования IList используйте ObservableCollection<T> и определите свой класс PersonCollection, как показано ниже:

public class PersonCollection : ObservableCollection<Person>
{}

Подробнее о классе ObservableCollection<T> можно прочитать здесь, который разработан специально для уведомлений об изменении коллекции в сценариях WPF DataBinding.

Как видно из определения в MSDN ниже, он уже реализует INotifyCollectionChanged

public class ObservableCollection<T> : Collection<T>, 
    INotifyCollectionChanged, INotifyPropertyChanged

Дополнительные статьи, которые помогут вам с использованием класса ObservableCollection в WPF, приведены ниже:

Создание и привязка к ObservableCollection
Введение в ObservableCollection в Wpf
Привязка данных к ObservableCollection в MVVM

person VSS    schedule 30.04.2013
comment
Спасибо за ответ. Но, к сожалению, я не смогу делать изменения в PersonCollection. - person Vikram; 30.04.2013