Cristian Cristian - 3 months ago 49
C# Question

BindingSource ListChanged event fires on position changes

From Microsoft:
"BindingSource.ListChanged Event occurs when the underlying list changes or an item in the list changes".

But in my example the event fires on every position change. The Form has an UserControl, a BindingSource and a Button.

The user control has one TextBox and two properties:

/// <summary>
/// Is working: ListChanged is not fired
/// </summary>
public override string Text
{
get { return textBox1.Text; }
set { textBox1.Text = value; }
}

/// <summary>
/// Is not working: ListChanged is fired on Position changes
/// </summary>
public string MyProperty
{
get { return textBox1.Text; }
set { textBox1.Text = value; }
}


The button on the form changes the position of the BindingSource:

void next_Click(object sender, EventArgs e)
{
bindingsource.Position += 1;
}


When I bind the control using the "Text" property the ListChanged event does not occurs, as expected:

myusercontrol1.DataBindings.Add("Text", bindingsource, "name");


but when I bind the control using "MyProperty" property the ListChanged event fires on position changes:

myusercontrol1.DataBindings.Add("MyProperty", bindingsource, "name");


I tried different DataSorces, like in this example:

public Example()
{
InitializeComponent();

string xml = @"<states>"
+ @"<state><name>Washington</name></state>"
+ @"<state><name>Oregon</name></state>"
+ @"<state><name>Florida</name></state>"
+ @"</states>";
byte[] xmlBytes = Encoding.UTF8.GetBytes(xml);
MemoryStream stream = new MemoryStream(xmlBytes, false);
DataSet set = new DataSet();
set.ReadXml(stream);

bindingsource.DataSource = set;
bindingsource.DataMember = "state";
bindingsource.ListChanged += BindingNavigator_ListChanged;

myusercontrol1.DataBindings.Add("MyProperty", bindingsource, "name");
}


How can I use MyProperty and avoid the ListChanged event fires on position changes? Why Text property is working as expected but MyProperty is not?

Thanks in advance,
Cristian

Answer

Why Text property is working as expected but MyProperty is not?

It's all about the change notifications. As you probably know, the Windows Forms data binding supports two types of source object change notifications - the object implementing INotifyPropertyChanged or providing {PropertyName}Changed named events.

Now look at your user control. First off, it doesn't implement INotifyPropertyChanged. However, there is a event called TextChanged, so when you data bind to Text property, the BindingSource will use that event to fire ListChanged. But when you bind to MyProperty, since there is no event called MyPropertyChanged, the data binding infrastructure is trying to emulate it with ListChanged event when the Position (hence the current object) changes.

With that being said, add the following to your user control:

public event EventHandler MyPropertyChanged
{
    add { textBox1.TextChanged += value; }
    remove { textBox1.TextChanged -= value; }
}

and data binding to your property will work as expected.

Comments