.NET Framework - BindingSource and CurrentChanged event

Asked By dvesta on 13-Sep-11 04:22 PM
The included program produces this output to the debug stream:

Changed!
Changed!
Changed!

Why does the event fire three times?  Can I configure it such that it
only fires when the Current item is actually different?

My source program follows:

using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Diagnostics;

namespace WindowsApplication3
{
static class Program
{
[STAThread]
static void Main()
{
BindingSource src = new BindingSource();
BindingList<string> list = new BindingList<string>(
new string[]
{
}
);

src.CurrentChanged += new EventHandler(src_CurrentChanged);
src.DataSource = list;
}

static void src_CurrentChanged(object sender, EventArgs e)
{
Debug.WriteLine("Changed!");
}
}
}




Peter Duniho replied to dvesta on 13-Sep-11 07:12 PM
Probably not.

I have not tested the scenario with .NET symbols installed, and so I
do not really know exactly what .NET is doing.  But being familiar with
similar implementations, I can hypothesize that from the framework's
point of view, the event really does occur three times.

At least two I can figure out off the top of my head: obviously when the
data source is changed, the Current property changes also.  But in
addition, probably there is code that kicks in after the data source
changes that explicitly sets the Current property, causing the event to
be raised again.

What the third time is, I do not have a good guess, but it is probably
something similar.  Maybe related to a default filtering or sorting that
the class does (that being one of the events the class is documented as
raising the event for).

Of course, one could argue that simply changing the data source
_should not_ result in the event being raised, or that having raised that
event, setting the Current property to the same thing it is already set
to should not raise the event, or that having internally set the Current
property when the data source changes, the code should not need to set
the Current property _again_.  And similar arguments can probably be
made for whatever is causing the third instance of the event being raised.

I'd probably even agree with that argument, barring some strong
justification from Microsoft to do otherwise.

But I do not see any way to alter the behavior of the BindingSource class
itself.  And there is a pretty good chance Microsoft would disagree with
the above argument, in spite of the awkward behavior.  And maybe they'd
even have a decent justification.

Fortunately, it should not be difficult to treat consecutive invocations
of the event handler when the Current property has not really changed,
simply by keeping track of what the property was the last time the event
was raised and comparing it to the current Current value.

In any case, I do recommend submitting a bug on the Connect web site, to
at least see what Microsoft says about it.  Maybe they'd even offer a
better work-around than I have.

In the meantime, you can console yourself with the fact that this guy is
seeing the event being raised not three times, but FOUR:
http://social.msdn.microsoft.com/forums/en-us/winformsdatacontrols/thread/99764A47-A49B-4FA1-9731-59148F3197E9

And no one ever replied to his question at all.  :(

Pete
dvesta replied to Peter Duniho on 14-Sep-11 11:24 AM
n.microsoft.com/forums/en-us/winformsdatacontrols/th...

Thanks, Peter.  When the property changes, I do some expensive
processing that is not _quite_ expensive enough to stick in a non-GUI
thread...unless it happens 3 times.

I worked around it by setting the datasource first, then subscribing
to the event.  In the event handler and immediately after subscribing
to the event, I call a function that does the work, so I avoid the
initial glut of events.