Settings invisible field values for user created rows in DataGridView

S

Sin Jeong-hun

My application has a DataGridView, and lets users input new rows in
it. It uses the VS.NET generated class mechanisms, so there are three
components like XXXBindingSource, XXXTableAdapter and XXXDataSet.

Everything is fine except that there is a hidden field (meaning a
field exists in the datatable but not displayed on the DataGridView)
and I need to set the value for it programatically for the newly input
rows by user. The value is determined at the moment when the user
creates a new row, since the field represents a category value which
is selected in a TreeView control at the moment. Which event should I
use, and how could I get the newly created row?

I tried XXXBindingSource.CurrentItemChanged, but I think it is not
what I'm looking for. Thank you for reading.
 
M

Marc Gravell

One option is to subscirbe to the AddingNew event of the
BindingSource, and set e.NewObject to whatever you want.

Alternatively - what is behind the BindingSource? If it is
BindingList<T>, you can override AddNewCore nad set what properties
you want.

Marc
 
S

Sin Jeong-hun

One option is to subscirbe to the AddingNew event of the
BindingSource, and set e.NewObject to whatever you want.

Alternatively - what is behind the BindingSource? If it is
BindingList<T>, you can override AddNewCore nad set what properties
you want.

Marc
Thank you for your answer.

The data source behind the DataGridView is a very simple .MDB (Access
database) which has a simple table named XXX (XXX is not the real
name) I tried to handle AddingNew as you recommended, but I don't know
what type of object should I set for the NewObject. Ideally, I don't
want to create a new object myself, I want to receive the object
(which represents the new row) created by the user when the user just
have typed a new row, and set only the value for the hidden field
while leaving all the values input by the user intact.

Anyways, I tried like
XXXDataSet.XXXRow. r = xxxDataSet.XXX.NewXXXRow();
r.HiddenField = 2;
e.NewObject = r;
but failed. I think XXXRow type is incorrect, but what type should I
set for it? Is it uncommon that setting hidden field value for newly
created row by user? I thought it should be common and there should be
already a practice for this.
 
M

Marc Gravell

First - note that row creation occurs as soon as you enter the new row
- so the other values might not be available at this point.

OK; two other things that occur:

1: since you are using a typed DataTable, override the OnTableNewRow
method?

protected override void
OnTableNewRow(DataTableNewRowEventArgs e)
{
// use base creation logic
base.OnTableNewRow(e);
DataRow row = e.Row;
// TODO: do something with row
}

2: Listen to the ListChanged event on the binding-source; in
particular for ItemAdded:

bindingSource1.ListChanged += bindingSource1_ListChanged;
void bindingSource1_ListChanged(object sender,
ListChangedEventArgs e)
{
if (e.ListChangedType == ListChangedType.ItemAdded)
{
object row = bindingSource1[e.NewIndex];
}
}

Either of those help any? You can also listen to
ListChangedType.ItemChanged if you want to get the values during
updates - but watch out for recursion - i.e. if you set a value
whenever you detect a value has changed... you can end up going in
circlues.

Marc
 
S

Sin Jeong-hun

First - note that row creation occurs as soon as you enter the new row
- so the other values might not be available at this point.

OK; two other things that occur:

1: since you are using a typed DataTable, override the OnTableNewRow
method?

            protected override void
OnTableNewRow(DataTableNewRowEventArgs e)
            {
                // use base creation logic
                base.OnTableNewRow(e);
                DataRow row = e.Row;
                // TODO: do something with row
            }

2: Listen to the ListChanged event on the binding-source; in
particular for ItemAdded:

    bindingSource1.ListChanged += bindingSource1_ListChanged;
    void bindingSource1_ListChanged(object sender,
ListChangedEventArgs e)
        {
            if (e.ListChangedType == ListChangedType.ItemAdded)
            {
                object row = bindingSource1[e.NewIndex];
            }
        }

Either of those help any? You can also listen to
ListChangedType.ItemChanged if you want to get the values during
updates - but watch out for recursion - i.e. if you set a value
whenever you detect a value has changed... you can end up going in
circlues.

Marc

Thank you Mr. Gravell. The second way seems to be working!
Method 1 doesn't seem to work, I tried to override OnTableNewRow, but
it didn't fired anyway.
Method 2 was OK. I tried like this;

if (e.ListChangedType ==
System.ComponentModel.ListChangedType.ItemAdded)
{
System.Data.DataRowView rv = xxxBindingSource[e.NewIndex] as
System.Data.DataRowView;
XXXDataSet.XXXRow r = rv.Row as XXXDataSet.XXXRow;
r.InvisibleField = 2;
}
Finally I can go on from there, thanks again.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top