I have an ObservableCollection in the ViewModel that add new entries when an ApplicationBar button is pressed in the View. The ListBox which is bound to this ObservableCollection doesnt show the new/updated entry, it does show the items of the collection when the application loads. The ViewModel does implement INotifyPropertyChanged and I do call NotifyPropertyChanged when an item is added to the ObservableCollection (or) set.
ViewModel - based on what is read from the server, new items are added to the observable collection.
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 - sets the datacontext and itemsource
<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);
}
Any Add/update to the observablecollection in the viewModel is not reflected in the listbox. i've read a bunch of places that notifypropertychanged is the solution, but i already have notifypropertychanged and still see the issue. Any ideas what i'm missing?
From @compoenet_tech's suggestion by adding the new item when the ApplicationBar buttin is pressed. I do see the listbox display the new item
SubsViewModel newitem = new SubsViewModel();
newitem.itemTitle = "test";
newitem.itemCount = test;
_itemssUnread.Add(newitem); test++;
So, doing the Add() outside the Dispatcher Invoke does work. But now the problem is that I get the new list from webservice using a callback, which is where i add the entries into unreaditems collection. which I cannot (??) do outside the dispatcher.
(web service) =callback=> ViewModel =observablecollection=> View
how does viewmodel get notified to update the collection outside a callback where i dont have to use dispather invoke? (or) use dispatcher invoke and not crash through cross thread reference.
Thanks
Please Instantiate the Observable collection before use.
In constructor of the MainViewModel write the following code like
public MainViewModel() { _itemsUnread = new ObservableCollection(); }
Function reader_PropertyChanged is not required to implement.
While calling the NotifyPropertyChanged use the Property Name as parameter like
public ObservableCollection UnreadItems { get { return _itemsUnread; } set { _itemsUnread = value; NotifyPropertyChanged("UnreadItems"); } }
A couple of notes:
1) According to MSDN, ObservableCollection already implements INotificatCollectionChanged for Silverlight, so you shouldn't have to reimplement it.
2) This code in the setter:
NotifyPropertyChanged("Updated");
has some issues:
a) it will only be executed when the entire collection object itself is changed, not when items within the collection are changed.
b) If a is implemented as you want it to be, then the string parameter should be the property that changed to UnreadItems.
Update
I also suspect (noted in the comments below) that adding the items in the Invoke is causing the notification messages to be lost. I recommend changing the code to add the items directly rather than in the Invoke statement.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With