BindingList.ListChanged event not firing

  • Thread starter Thread starter Zoodor
  • Start date Start date
Z

Zoodor

I have some code, in .NET 2.0 that is making use of the BindingList<T> class.
When an item is added to the list, the ListChanged event is fired as
expected. However, if I change the value of one of the properties of an item
in the list, the ListChanged event is not raised. I am sure I must be missing
something pretty simple, but cannot figure out what. Can anybody help me?

RaiseListChangedEvents is set to true and the object in the list that is
being changed implements the INotifyPropertyChanged interface (and is
definately raising the PropertyChanged event (or at least trying to, but
nothing is listening) when the property's value is changed - I have checked
this using the debugger).

Some example code that is "misbehaving" is:

BindingList<CustomType> list = new BindingList<CustomType>();

CustomType item = new CustomType();
list.Add( item );

list.ListChanged += List_ListChanged;

item.SomeProperty = "NewValue"; // No ListChanged event fired

Thanks in advance
 
I would strongly suspect your event code. The following shows
BindingList<T> working, as long as you get this code correct. Since
this code isn't much fun to repeat, I've moved it out into a utility
method so that it can be re-used from any class [I've included both
2005 and 2008 syntax].

using System;
using System.Collections.Generic;
using System.ComponentModel;
static class Program
{
static void Main()
{
// test property changed in isolation
CustomType item = new CustomType();
item.PropertyChanged += delegate (object sender,
PropertyChangedEventArgs args)
{
Console.WriteLine("PropertyChanged: {0}",
args.PropertyName);
};
item.SomeProperty = "Foo";

// start again, now with a list
item = new CustomType();
BindingList<CustomType> list = new BindingList<CustomType>();
list.ListChanged += delegate(object sender,
ListChangedEventArgs args)
{
Console.WriteLine("ListChanged: {0}: {1}",
args.ListChangedType, args.NewIndex);
};
list.Add(item);
item.SomeProperty = "Bar";
}
}

// utility method...
public static class NotificationHelper
{
// VS2005: remove the "this"
public static void UpdateField<T>(this INotifyPropertyChanged
sender, ref T field, T value,
PropertyChangedEventHandler handler, string propertyName)
{
if (!EqualityComparer<T>.Default.Equals(field, value))
{
field = value;
if (handler != null)
{
handler(sender, new
PropertyChangedEventArgs(propertyName));
}
}
}
}
public class CustomType : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

private string someProperty;
public string SomeProperty
{
get { return someProperty; }
set {
// VS2008 usage
this.UpdateField(ref someProperty, value, PropertyChanged,
"SomeProperty");
// VS2005 usage
//NotificationHelper.UpdateField(this, ref someProperty,
value, PropertyChanged, "SomeProperty");
}
}
}
 
By the way - is CustomType a class or a struct? You could have all
manner of issues trying to bind to structs (which generally shouldn't
be mutable anyway...)

Marc
 
Thank you very much for your reply.

I ran the code you supplied and it worked. This confused me, and after
investigating I have discovered that its due to a change I made for uploading
the code that I didn't realise would have an impact (oops!). Basically, my
BindingList is actually declared using an interface type:

BindingList<ICustomInterface> list = new BindingList<ICustomInterface>();

and whilst every instance stored in the list is of a class that also
implements INotifyPropertyChanged, ICustomInterface doesn't extend it itself.
I suppose I should have considered this, though it would be nice if the
BindingList checked the items added, rather than simply relying on the
generic type parameter. Oh well.

Thanks again.
 
Back
Top