Why does ObservableCollection throws an exception when being modified?
My application uses a WPF DataGrid
. One of the columns is a template column that contains a ComboBox
bound to an ObservableCollection
of the entity which feeds the row. When I add a value to the ObservableCollection
, a NullReferenceException
is thrown.
Has anybody an idea why this happens? Here is the stack trace of the exception:
at MS.Internal.Data.PropertyPathWorker.DetermineWhetherDBNullIsValid() at MS.Internal.Data.PropertyPathWorker.get_IsDBNullValidForUpdate() at MS.Internal.Data.ClrBindingWorker.get_IsDBNullValidForUpdate() at System.Windows.Data.BindingExpression.ConvertProposedValue(Object value) at System.Windows.Data.BindingExpressionBase.UpdateValue() at System.Windows.Data.BindingExpression.Update(Boolean synchronous) at System.Windows.Data.BindingExpressionBase.Dirty() at System.Windows.Data.BindingExpression.SetValue(DependencyObject d, DependencyProperty dp, Object value) at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, OperationType operationType, Boolean isInternal) at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value) at System.Windows.Controls.Primitives.Selector.UpdatePublicSelectionProperties() at System.Windows.Controls.Primitives.Selector.SelectionChanger.End() at System.Windows.Controls.Primitives.Selector.OnItemsChanged(NotifyCollectionChangedEventArgs e) at System.Windows.Controls.ItemsControl.OnItemCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e) at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e) at System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args) at System.Windows.Controls.ItemCollection.System.Windows.IWeakEventListener.ReceiveWeakEvent(Type managerType, Object sender, EventArgs e) at System.Windows.WeakEventManager.DeliverEventToList(Object sender, EventArgs args, ListenerList list) at System.Windows.WeakEventManager.DeliverEvent(Object sender, EventArgs args) at System.Collections.Specialized.CollectionChangedEventManager.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args) at System.Windows.Data.CollectionView.OnCollectionChanged(NotifyCollectionChangedEventArgs args) at System.Windows.Data.ListColle开发者_Go百科ctionView.ProcessCollectionChangedWithAdjustedIndex(NotifyCollectionChangedEventArgs args, Int32 adjustedOldIndex, Int32 adjustedNewIndex) at System.Windows.Data.ListCollectionView.ProcessCollectionChanged(NotifyCollectionChangedEventArgs args) at System.Windows.Data.CollectionView.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args) at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e) at System.Collections.ObjectModel.ObservableCollection`1.InsertItem(Int32 index, T item) at System.Collections.ObjectModel.Collection`1.Add(T item) at ORF.PersonBook.IdentityModule.Model.SubsidiaryModel.AddRoom(RoomModel room) in C:\Project\Phoenix\Development\src\ORF.PersonBook.IdentityModule\Model\SubsidiaryModel.cs:line 127
Finally I found the reason for the exception. The problem occurs when you are removing the selected item from the list. Below I've posted an incomplete piece of code.
<!-- XAML -->
<ListBox ItemsSource="{Binding Rooms}" SelectedItem="{Binding SelectedRoom}">
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel>
<Button Content="remove" DockPanel.Dock="Right" Command="{Binding Some Remove Command}" />
<TextBlock Text="{Binding Name}" />
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And the view model:
// View Model
public ObservableCollection<Room> Rooms { get; private set; }
public Room SelectedRoom { get; set; }
public RemoveRoom()
{
var room = SelectedRoom;
//SelectedRoom = null; // Uncomment this line to avoid the exception
Rooms.Remove(room);
}
The solution is to first set the selected item to null (or any other item) before actually removing the item from the list.
Oliver Hanappi
Is your Room class object actually instantiated? It looks as if your adding an uninitialised value.
精彩评论