I am developing a WPF application in C# 4.5.2 in Visual Studio 2017. Within the application I have a custom object that gets rolled into an ObservableCollection<T> for later processing. I want to be able to handle this CollectionChanged event if/when necessary.
I added the appropriate decoration to the class (: INotifyPropertyChanged), added the event and handler, and attributed each property in my object with the Interface PropertyChanged:
public class OrderLineItem : INotifyPropertyChanged
{
private int _lineItemNumber;
public int LineItemNumber
{
get => _lineItemNumber;
set { _lineItemNumber = value; OnPropertyChanged(); }
}
private int _quantity;
public int Quantity
{
get => _quantity;
set { _quantity = value; OnPropertyChanged(); }
}
private string _partNumber;
public string PartNumber
{
get => _partNumber;
set { _partNumber = value; OnPropertyChanged(); }
}
private Hinge _hinged;
public Hinge Hinging
{
get => _hinged;
set { _hinged = value; OnPropertyChanged(); }
}
private Finish _finished;
public Finish Finished
{
get => _finished;
set { _finished = value; OnPropertyChanged(); }
}
private decimal _unitPrice;
public decimal UnitPrice
{
get => _unitPrice;
set { _unitPrice = value; OnPropertyChanged(); }
}
private decimal _modifyPrice;
public decimal ModifyPrice
{
get => _modifyPrice;
set { _modifyPrice = value; OnPropertyChanged(); }
}
private decimal _extendedPrice;
public decimal ExtendedPrice
{
get => _extendedPrice;
set { _extendedPrice = value; OnPropertyChanged(); }
}
private List<string> _modifications;
public List<string> Modifications
{
get => _modifications;
set { _modifications = value; OnPropertyChanged(); }
}
private CabinetType _type;
public CabinetType Type
{
get => _type;
set { _type = value; OnPropertyChanged(); }
}
private string _display;
public string Display
{
get => _display;
set { _display = value; OnPropertyChanged(); }
}
public enum Hinge { None = 0, L, R, BD }
public enum Finish { None = 0, L, R, B }
public OrderLineItem()
{
LineItemNumber = -1;
Quantity = -1;
PartNumber = string.Empty;
Hinging = Hinge.None;
Finished = Finish.None;
UnitPrice = 0.00m;
ModifyPrice = 0.00m;
ExtendedPrice = 0.00m;
Modifications = new List<string>();
Type = CabinetType.None;
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
In my MainWindow.xaml.cs file I have added the .CollectionChanged handler to my ObservableCollection<T> and the .PropertyChanged handler to my object:
private void AddedItemsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (OrderLineItem newItem in e.NewItems)
{
_addedItems.Add(newItem);
newItem.PropertyChanged += OnItemPropertyChanged;
}
}
if (e.OldItems != null)
{
foreach (OrderLineItem oldItem in e.OldItems)
{
_addedItems.Add(oldItem);
oldItem.PropertyChanged -= OnItemPropertyChanged;
}
}
}
private void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e)
{
OrderLineItem item = sender as OrderLineItem;
if (item != null) _addedItems.Add(item);
}
Any time I add an item to the collection I add the PropertyChanged handler to it:
...
item.PropertyChanged += ItemOnPropertyChanged;
...
This collection gets displayed in a DataGrid via the .ItemsSource property.
The issue in this question's title only happens after implementing the INotifyPropertyChanged and its associated methods/interfaces etc.
The stack trace I was able to get does not provide me with any useful information (line number, file, method etc) to attempt to debug this. I did enable all of the debugging options to make sure I wasn't ignoring any potential exceptions. Here is a pastebin of the exception. The line number indicated is this:
AppDomain.CurrentDomain.UnhandledException +=
(sender, args) => throw new Exception("Unhandled exception: " + args.ExceptionObject);
If I do not have this line, or comment it out this is a pastebin of the exception I get instead.
Any idea of how I should proceed trying to solve this, besides not implementing the CollectionChanged event?
There seem to be a relation with INotifyPropertyChanged and Binding rules but I don't know which one.
I got into the same issue: implementing INotifyPropertyChanged on a PropertyGrid item triggered the Key cannot be null binding error. By the way, it was one of the most useless and random error logs I have seen.
Cannot save value from target back to source.
BindingExpression:[info on an unrelated parent binding...]
ArgumentNullException:'System.ArgumentNullException: Key cannot be null.
After some time, I found out about weird Binding behaviors in old wpf versions where adding Path= to the bindings could fix it, but that wasn't it.
I actually had a Binding in code-behind like so:
void GetBinding(PropertyItem propertyItem)
{
return new Binding($"({propertyItem.PropertyName})")
{
//[Source, Mode, etc...]
}
}
And the code worked for both properties and attached properties, but stopped working right after implementing the property notifier on this class. Maybe a more strict rule got triggered and flagged my property as not being an "attached" one, but it worked before without the interface.
So, I removed the parenthesis and it works now.
return new Binding($"{propertyItem.PropertyName}")
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