Windows Develop Bookmark and Share   
 index > Windows Forms Data Controls and Databinding > DataGridView - DefaultValuesNeeded event handler cannot assign to e.Row.Cells[0].Value
 

DataGridView - DefaultValuesNeeded event handler cannot assign to e.Row.Cells[0].Value

I've written a DefaultValuesEvent handler (VS2005 C#) for my db table bound DataGridView so that I can seed a value to the ID column of the new row entry in the grid, pretty much as the documentation sample indicates (see http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.defaultvaluesneeded.aspx). But thee.Row.Cells[0].Value property stubbornly refuses to be assigned anything and just reverts to null regardless of what I try to put into it. Any ideas?
taci  Tuesday, September 22, 2009 11:34 AM
Hi taci,

> But the e.Row.Cells[0].Value property stubbornly refuses to be assigned anything and just reverts to null regardless of what I try to put into it.

Do you mean the new row cell [0] doesn’t display the value you have set, but with empty string? Does it work for other cells? E.g. cell[1], cell[2]

According to my test, the default new row value is just the one I have set for the cell in the DefaultValuesNeeded handled method. From your post, I know the column you want to set is an ID column. Does it a primary key column? Could you please post your code? That can help us to understand it clearly.

Sincerely,
Kira Qian
Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework!
Kira Qian  Wednesday, September 23, 2009 2:55 AM
Hello Kira
Here's my code.
First I register the event handler:

            this.UserDataGridView.DefaultValuesNeeded += new DataGridViewRowEventHandler(UserDataGridView_DefaultValuesNeeded);

Here's the event handler:

        void UserDataGridView_DefaultValuesNeeded(object sender, DataGridViewRowEventArgs e)
        {
            e.Row.Cells["userIDDataGridViewTextBoxColumn"].Value = 1;
            foreach (DataRow dr in cCFUserTableAdapter.GetData().Rows)
            {
                Configure.ContactCenterDataSet.CCFUserRow ur =
                    (Configure.ContactCenterDataSet.CCFUserRow)dr;
                if (ur.UserID >
                    (Int32)e.Row.Cells["userIDDataGridViewTextBoxColumn"].Value)
                {
                    e.Row.Cells["userIDDataGridViewTextBoxColumn"].Value =
                        ur.UserID + 1;
                }
            }
        }

What I'm trying to do is seed the id column of the new row with a value 1 greater than the current largest id value in the grid.
I get a NullReferenceExceptionat the line:

                if (ur.UserID >
                    (Int32)e.Row.Cells["userIDDataGridViewTextBoxColumn"].Value)


of the event handler because the e.Row.Cells["userIDDataGridViewTextBoxColumn"].Value is null, despite being assigned at the start of the event handler.
When I step through in the debugger and watch the value property it does indeed remain null even immediately after the initial assignment step.
thanks
taci
PS Yes - the ID column is a primary key on the db.
taci  Wednesday, September 23, 2009 9:33 AM

Hi taci,

The “e.Row.Cells[i].Value�in DefaultValuesNeeded handled method is for set. When you get its value before setting, it always return null.

Based on my understanding of your code, I think the purpose of it is to get the current max id in the data source. So you can generate the next id (max + 1). My suggestion is you can make a method which will return the max id (GetMaxID). That method will loop through the rows in the data source and get the max one. In the UserDataGridView_DefaultValuesNeeded method, set e.Row.Cells["userIDDataGridViewTextBoxColumn"].Value = GetMaxID() + 1; something like that.

Do you have any difficulty to code that GetMaxID method? If you need any help, please post the detail of your datasource (DataTable/DataSet) structure.

Sincerely,

Kira Qian

Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com


Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework!
Kira Qian  Thursday, September 24, 2009 5:02 AM
Hello Kira
But I doset the e.Row.Cells[0].Value property - to 1. I've heard of read-only properties, butnot write-only ones!
I've re-written the event handler as below:
        void UserDataGridView_DefaultValuesNeeded(object sender, DataGridViewRowEventArgs e)
        {
            int newId = 1;
            foreach (DataRow dr in cCFUserTableAdapter.GetData().Rows)
            {
                ContactCenterDataSet.CCFUserRow ur =
                    (ContactCenterDataSet.CCFUserRow)dr;
                if (ur.UserID >= newId)
                {
                    newId = ur.UserID + 1;
                }
            }
            e.Row.Cells["userIDDataGridViewTextBoxColumn"].Value = newId;
        }
This seems to work ok, although I'm not very happy about the clunky loop.
Is this the sort of thing you had in mind, or do you know of a more efficient way of doing it?
thanks
taci
taci  Thursday, September 24, 2009 9:07 AM

Hello taci,

I missed the “e.Row.Cells["userIDDataGridViewTextBoxColumn"].Value = 1�line at the first look, so sorry. After further test, I do find the e.Row.Cells[i].Value always return null even if I have set it first.

You have done right. This code is similar to my thinking. Actually my thinking is as follow.

private int GetMaxID()

{

int maxId = 1;

foreach (DataRow dr in cCFUserTableAdapter.GetData().Rows)

{

ContactCenterDataSet.CCFUserRow ur =

(ContactCenterDataSet.CCFUserRow)dr;

if (ur.UserID > newId)

{

maxId = ur.UserID;

}

}

return maxId;

}

void UserDataGridView_DefaultValuesNeeded(object sender, DataGridViewRowEventArgs e)

{

e.Row.Cells["userIDDataGridViewTextBoxColumn"].Value = GetMaxID() + 1;

}

If you want to find a more efficient solution, may be you can create a variable in your form, named MaxID. When the form loaded, you can put a loop to get the max id from data source and set MaxID variable. So you don’t need to do loop each time to set cell value. Just use MaxID + 1 as the value and make MaxID = MaxID + 1. This way is more efficient.

Hope it helps.

Sincerely,

Kira Qian

Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework!
Kira Qian  Thursday, September 24, 2009 9:35 AM
Thanks Kira, good ideas. I suppose ideally I'd get the MaxID to refresh when a new row is added to the table.
On a related point, I'd alsolike to extend my DGV to include supplementary user data from another db on the same server.
i.e. join from the ContactCenter.CCFUser table (which is the bound source for my current DGV implementation) to <OtherDB>.<OtherUserInfoTable>using ContactCenter.CCFUser.UserID == <OtherDB>.<OtherUserInfoTable>.UserID.
I'veseen various suggestions for implementing the join (e.g. http://support.microsoft.com/kb/326080), but I've implementedmy current DGV using the designer, so I'm not sure if I will have to throw my current implementation away and start again with a hand-written solution, or if its possible/easier to adapt what I've already got in some way. Or if there's any designer support for the join type of data source for the DGV.
The other concern I haveis whether theDGV will still support insert, update and delete for the 2 joined tables or if there's anything special I need to do to make that work properly.
Any suggestions/advice appreciated.
thanks
taci
taci  Thursday, September 24, 2009 2:50 PM
Hello taci,

I am glad my suggestion works for you.

For the join table, I think you don’t need to abandon current design and do hard coding totally. Visual Studio has generated useful code for you to make the work conveniently. You can get the generated DataTable and TableAdapter to fetch data from database. You can call TableAdapter.Fill method to fill the strongly typed DataTables and use the KB article to join these tables.

But when you do that, the insert, update and delete won’t generate sql for you. You need to hard code for these operations.

Sincerely,
Kira Qian
Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework!
Kira Qian  Friday, September 25, 2009 2:29 AM
Hi taci,

I am writing to check the status of the issue on your side. Could you please let me know if the suggestion works for you? If you have any questions or concerns, please feel free to let me know. I will be more than happy to be of assistance.

Sincerely,
Kira Qian
Send us any feedback you have about the help from MSFT at fbmsdn[At]microsoft.com
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework!
Kira Qian  Wednesday, October 07, 2009 7:15 AM

You can use google to search for other answers

Custom Search

More Threads

• Haw to update
• TreeView Control
• DataGridView Error
• Reading from XML and bound to DatagridView : Adding rows dynamically
• Datagridview image column
• How To set DataSource to global DataSet and edit columns etc. in Design View
• how to reposition my user controls over a web page
• Can a DataViewGrid have a RadioButton-like setup?
• Navigator's Broke!
• How to use PropertyManager