I want to customize the addition of a new item into a BindingSource
(all strongly-typed) as described on the following MSDN Article:
How to: Customize Item Addition with the Windows Forms BindingSource
The code below results in InvalidOperationException
: Objects added to a BindingSource's list must all be of the same type. Also, the object myTypesBindingSource.Current
seems to be a DataRowView
with my relevant row inside.
How can I customize the addition of a strongly-typed BindingSource
?
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.someDataSet = new myDB.SomeDataSet();
this.myTypesBindingSource = new System.Windows.Forms.BindingSource(this.components);
this.myTypesTableAdapter = new myDB.SomeDataSetTableAdapters.myTypesTableAdapter();
this.tableAdapterManager = new myDB.SomeDataSetTableAdapters.TableAdapterManager();
this.myTypesBindingNavigator = new System.Windows.Forms.BindingNavigator(this.components);
this.someIntValueTextBox = new System.Windows.Forms.TextBox();
// someDataSet
this.someDataSet.DataSetName = "SomeDataSet";
this.someDataSet.SchemaSerializationMode = System.Data.SchemaSerializationMode.IncludeSchema;
// myTypesBindingSource
// As generated:
// this.myTypesBindingSource.DataMember = "myTypes";
// this.myTypesBindingSource.DataSource = this.someDataSet;
this.myTypesBindingSource.DataSource = this.someDataSet;
this.myTypesBindingSource.AddingNew += new System.ComponentModel.AddingNewEventHandler(this.myTypesBindingSource_AddingNew);
// myTypesTableAdapter
this.myTypesTableAdapter.ClearBeforeFill = true;
// tableAdapterManager
this.tableAdapterManager.BackupDataSetBeforeUpdate = false;
this.tableAdapterManager.myTypesTableAdapter = this.myTypesTableAdapter;
this.tableAdapterManager.UpdateOrder = myDB.SomeDataSetTableAdapters.TableAdapterManager.UpdateOrderOption.InsertUpdateDelete;
// someIntValueTextBox
this.someIntValueTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.myTypesBindingSource, "someIntValue", true));
this.someIntValueTextBox.Name = "someIntValueTextBox";
}
private void myTypesBindingSource_AddingNew(object sender, AddingNewEventArgs e)
{
SomeDataSet.myTypesRow newRow = someDataSet.myTypes.NewmyTypesRow();
newRow.someIntValue = 99;
e.NewObject = newRow;
}
In the example, it is not a strongly typed
BindingSource
. As a matter of fact, theAddingNewEventArgs.NewObject
property is an object. So, assigning it any derived type shall make it.Also, notice that the example uses a class object
DemoCustomer
, it is noDataSet.Tables[0].Row
which returns aDataRow
. The game is a bit different, in my point of view, when using aDataSet
.When one uses a
DataSet
, you'll have to set only aDataTable
as theBindingSource.DataSource
, making you write something like:This way, when you add an item to the
BindingSource.List
usingBindingSource.AddNew()
, theBindingSource
"knows" that it has aDataTable
as itsDataSource
, so it calls theDataTable.NewRow()
method and a newDataRow
is added to yourDataTable
! Thus, having aDataRow
to handle instead of a simple object.If you want to do similar to what the example on MSDN says, you'll have to create the row yourself.
This way, you shall be able to tell what default values you want.
Otherwise, if not, you might as well try this:
The weakness here is whenever you change the underlying database table column name, you'll have to come here, change the name of your
intColumn
, and recompile, and redeploy.Besides, this shall not happen often, so it might be worthy depending on your environmental context.
After having paid more attention to:
From MSDN:
DataRowView
This means that when adding a new row, you're actually adding a
DataRowView
. You may access the current row by accessing itsDataRowView.Row
property.Taking this into consideration, you might perhaps change the proposed solution in my initial answer to this:
EDIT: (by Steven) Final Code