I have an ObservableCollection _cableList
containing objects of type CableViewModel
. The CableViewModel
objects have a boolean property IsInDB
that should be set if another property Type
is listed i another collection. I listen to the PropertyChanged
event in order to update the IsInDB
property. This works as intended but I also need to update the IsInDB
property for items that are added to the collection. I attempt to solve this with the following code:
public MainViewModel()
{
_cableList = new ObservableCollection<CableViewModel>();
_cableList.CollectionChanged += _cableListChanged;
}
private void _cableListChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if(e.OldItems != null)
{
foreach (INotifyPropertyChanged item in e.OldItems)
item.PropertyChanged -= cablePropertyChanged;
}
if(e.NewItems != null)
{
foreach (INotifyPropertyChanged item in e.NewItems)
{
item.PropertyChanged += cablePropertyChanged;
// This causes an exception
MessageBox.Show("Collection changed - new Item");
var x = (CableViewModel)item;
x.IsInDB = IsInCableDB(x.Type);
}
}
}
The code causes an System.InvalidOperationException
that says something like "An ItemsControl
is inconsistent with its object source" or at least that´s my attempt to translate from the Swedish error message.
What is wrong with my code? Is there a another way to solve the task?
EDIT
I did not show the complete code in my original post as I didn't think it was related to the exception. But I was wrong.
In my original post I did not show or mention that I showed a MessageBox
for debugging purposes. It was shown each time a new object was added to the collection. The code above is now edited so that MessageBox.Show
line is included. After posting the original message here I removed the MessageBox
from the code and as a result the exception disappeared. Did the MessageBox
cause the UI to get out of sync with the collection? (The ObservableCollection
is bound to a DataGrid
)
In that case I would suggest using ReactiveList and use observables instead of events - it makes lots of threading problems go away.
On the plus side, you can then do something like this:
_cableList.ItemChanged.Where(x => x.PropertyName == "Cable").Select(x => x.Sender).Subscribe(x => {
//do something with the object
});
_cableList.ItemsAdded.Subscribe(x => x.IsInDB = IsInCableDB(x.Type);
Ehh... my mistake. When authoring the code I added messageboxes to learn what was going on. Each time the CollectionChanged
was triggered a messagebox was shown. When I removed the messageboxes the exceptions disappeared. Did the messageboxes cause the UI get out of sync with the data?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.