I’m using mvvm-light and I noticed this strange behavior about the RaisePropertyChanged.
xaml:
<ListBox ItemsSource="{Binding Collection}"/>
<TextBlock Text="{Binding Text}"/>
Observable class:
public class A : ObservableObject
{
private string _b;
public string B
{
get { return this._b; }
set
{
this._b = value;
this.RaisePropertyChanged("B");
}
}
}
vm:
public MainViewModel(IDataService dataService) { this.Collection = new List<A>(...); }
public RelayCommand Command1
{
get
{
return this._command1 ?? (this._command1= new RelayCommand(() =>
{
this.Collection.Add(new A());
this.Collection[2].B = "updated";
this.RaisePropertyChanged("Collection");
this.RaisePropertyChanged("Text");
}));
}
}
public RelayCommand Command2
{
get { return this._command2?? (this._command2 = new RelayCommand(() => { this.Text++; })); }
}
public List<A> Collection { get; set; }
public int Text { get; set; }
So, RaisePropertyChanged(“Collection”) doesn’t update the binding while RaisePropertyChanged(“Text”) do. I can see it by executing the Command2 several times and the Command1 after that. If the Collection is an ObservableCollection then new element shows in a view, but updated item isn’t, which means an internal mechanism of an ObservableCollection works, but not the RaisePropertyChanged.
First, an explanation of the issue:
On Windows Phone, when setting a value for a dependency property, the framework internally check if the new value is different from the old one (for optimization purpose maybe). When you raise the
PropertyChangedevent or directly re-assign your collection to theItemsSourceproperty (which is just a wrapper around theItemsControl.ItemsSourcePropertydependency property), the framework detects that the value actually didn’t change and doesn’t update the property. Therefore, theListBoxis never notified of your changes, and isn’t updated.The
ObservableCollectionworks because it uses a whole different mechanism: theListBoxdirectly subscribes to theCollectionChangedevent of your collection, and thus isn’t hindered by the limitations of the dependency properties.Now, how to get around this limitation? The only workarounds I can think of are:
ObservableCollectioninstead of aListnullto theItemsSourceproperty of yourListBox, then re-assign your collectionBind the
ListBoxto a property that will return a different collection every time it’s called: