Данные ListBox, привязанные к ObservableCollection в Windows Phone MVVM, не обновляются после добавления - PullRequest
3 голосов
/ 21 декабря 2011

У меня есть ObservableCollection во ViewModel, которая добавляет новые записи при нажатии кнопки ApplicationBar в View. ListBox, связанный с этим ObservableCollection, не показывает новую / обновленную запись, он показывает элементы коллекции при загрузке приложения. ViewModel реализует INotifyPropertyChanged, и я вызываю NotifyPropertyChanged, когда элемент добавляется в набор ObservableCollection (или).

ViewModel - в зависимости от того, что читается с сервера, в наблюдаемую коллекцию добавляются новые элементы.

public class MainViewModel : INotifyPropertyChanged
{
    private ObservableCollection<SubsViewModel> _itemsUnread;
    public ObservableCollection<SubsViewModel> UnreadItems
    {
        get
        {
            return _itemsUnread;
        }
        set
        {
            _itemsUnread = value;
            NotifyPropertyChanged("Updated");
        }
    }

   void reader_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        switch (e.PropertyName)
        {
            case "Updated":

                Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        UnreadItems.Clear();

                        foreach (ItemViewModel subs in ItemsAll)
                        {
                                ....
                                UnreadItems.Add(subs);
                        }
                    }
                );

                IsDataUpdated = true;

                NotifyPropertyChanged(e.PropertyName);

                break;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String propertyName)
    {
        if (null != this.PropertyChanged)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

view - устанавливает текстовый источник данных и источник данных

            <ListBox x:Name="SecondListBox" Margin="0,0,-12,0" ItemsSource="{Binding UnreadItems, Mode=TwoWay}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Margin="0,0,0,7">
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding ItemTitle}" TextWrapping="NoWrap" Margin="12,0,0,0" Style="{StaticResource PhoneTextLargeStyle}"/>
...

    public MainPage()
    {
        _mainView = new MainViewModel();
        InitializeComponent();

        // Set the data context of the listbox control to the sample data
        DataContext = _mainView;
        this.Loaded += new RoutedEventHandler(MainPage_Loaded);
    }

Любое добавление / обновление наблюдаемой коллекции в viewModel не отражается в списке. Я прочитал несколько мест, где notifypropertychanged - это решение, но я уже уведомил noperpropertychanged и все еще вижу проблему. Есть идеи, что мне не хватает?

По предложению @ compoenet_tech добавив новый элемент при нажатии кнопки ApplicationBar. Я вижу, что в списке отображается новый элемент

SubsViewModel newitem = new SubsViewModel();
newitem.itemTitle = "test";
newitem.itemCount = test;
_itemssUnread.Add(newitem); test++;

Итак, выполнение Add () вне Dispatcher Invoke работает. Но теперь проблема в том, что я получаю новый список из веб-сервиса, используя обратный вызов, где я добавляю записи в коллекцию unreaditems. что я не могу (??) сделать вне диспетчера.

(web service) =callback=> ViewModel =observablecollection=> View

как viewmodel получает уведомление об обновлении коллекции вне обратного вызова, где мне не нужно использовать dispather invoke? (или) использовать диспетчерский вызов и не вызывать сбой через перекрестную ссылку.

Спасибо

Ответы [ 3 ]

2 голосов
/ 21 декабря 2011
  1. Пожалуйста, ознакомьтесь с коллекцией Observable перед использованием. В конструкторе MainViewModel напишите следующий код как

    публичный MainViewModel () { _itemsUnread = new ObservableCollection (); }

  2. Функция reader_PropertyChanged не требуется для реализации.

  3. При вызове NotifyPropertyChanged используйте имя свойства в качестве параметра, например

    public ObservableCollection UnreadItems { получить { return _itemsUnread; } задавать { _itemsUnread = значение; NotifyPropertyChanged ( "UnreadItems"); } }

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

Пара заметок:

1) Согласно MSDN , ObservableCollection уже реализует INotificatCollectionChanged для Silverlight, поэтому вам не нужно его переопределять.

2) Этот код в установщике:

        NotifyPropertyChanged("Updated");

имеет некоторые проблемы:

a) он будет выполняться только при изменении самого объекта коллекции, а не при изменении элементов в коллекции.

b) Если a реализован так, как вы хотите, то строковым параметром должно быть свойство, которое было изменено на UnreadItems.

Обновление

Я также подозреваю (отмечено в комментариях ниже), что добавление элементов в Invoke приводит к потере уведомительных сообщений. Я рекомендую изменить код, чтобы добавлять элементы напрямую, а не в оператор Invoke.

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

Ваше свойство UnreadItems должно быть инициализировано в конструкторе с

UnreadItems = new ObservableCollection ();

...