It's not, here's the dataview approach:
public Form1()
{
InitializeComponent();
DataTable table = new DataTable();
ResultsetFields fields = new ResultsetFields(2);
fields.DefineField(ContactFields.ContactId, 0);
fields.DefineField(ContactFields.FirstName, 1);
new DataAccessAdapter().FetchTypedList(fields, table, null);
DataView toBind = table.DefaultView;
listBox1.DataSource = toBind;
listBox1.DisplayMember = ContactFields.FirstName.Name;
textBox2.DataBindings.Add("Text", table, ContactFields.FirstName.Name);
toBind.ListChanged += collection_ListChanged;
foreach(DataRowView row in toBind )
row.PropertyChanged += contact_PropertyChanged;
}
void contact_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
listBox2.Items.Add("DataRowView.PropertyChanged");
}
void collection_ListChanged(object sender, System.ComponentModel.ListChangedEventArgs e)
{
listBox2.Items.Add("DataView.ListChanged");
}
private void button1_Click(object sender, System.EventArgs e)
{
DataView view = (DataView)listBox1.DataSource;
view[listBox1.SelectedIndex]["FirstName"] = "Test";
}
exactly the same behavior.
Though indeed, when a datatable is bound, it's not showing this behavior, then it indeed shows the change immediately:
public Form1()
{
InitializeComponent();
DataTable table = new DataTable();
ResultsetFields fields = new ResultsetFields(2);
fields.DefineField(ContactFields.ContactId, 0);
fields.DefineField(ContactFields.FirstName, 1);
new DataAccessAdapter().FetchTypedList(fields, table, null);
DataView toBind = table.DefaultView;
listBox1.DataSource = table;
listBox1.DisplayMember = ContactFields.FirstName.Name;
textBox2.DataBindings.Add("Text", table, ContactFields.FirstName.Name);
toBind.ListChanged += collection_ListChanged;
foreach(DataRowView row in toBind )
row.PropertyChanged += contact_PropertyChanged;
}
void contact_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
listBox2.Items.Add("DataRowView.PropertyChanged");
}
void collection_ListChanged(object sender, System.ComponentModel.ListChangedEventArgs e)
{
listBox2.Items.Add("DataView.ListChanged");
}
private void button1_Click(object sender, System.EventArgs e)
{
//DataView view = (DataView)listBox1.DataSource;
//view[listBox1.SelectedIndex]["FirstName"] = "Test";
DataTable table = (DataTable)listBox1.DataSource;
table.Rows[listBox1.SelectedIndex]["FirstName"] = "Test";
}
This is very strange, because a datatable implements, similar to EntityCollection, IListSource, so it binds through it's default dataview (which I bind in my example above) so it should show exactly the same behavior as the dataview code snippet above. Though it doesn't.
What's strange in the dataview bind example is that it doesn't even raise the propertychanged event, it does that when I click another row. Though in the datatable approach, it does this immediately.
When I bind the collection though a bindingsource, it behaves the same as without a datasource
Now, when I place a breakpoint in EntityBase2.BeginEdit(), It does get called. Simply through the listbox control. So binding to the listbox control implies complex databinding ('complex' is the term MS uses, it's simply a name for defining the databinding type) otherwise BeginEdit wouldn't be called.
I can't intercept calls to the BeginEdit methods on the dataview/table so I can't test if these are called as well, but I doubt they will be called when the datatable is bound but the method IS called when a dataview is bound directly, simply because it postpones the events.
This IMHO implies hardcoded checks on datatable somewhere in the currencymanager, as I don't have any other explanation why our code gets a call to BeginEdit (and thus HAS TO postpone events!) and datatable apparently doesn't but dataview does. (so the datasource type is apparently checked to see if it's a datatable... what else would be the explanation for the fact that when you bind a dataview it simply behaves like the entitycollection...).