"Invalid Cast Exception was Unhandled" when accessing the DataBoundItem of a C# DataGridView Row

Posted on 2009-05-17
Medium Priority
Last Modified: 2013-12-17
When I click on a DataGridRow in my C# program it accesses the code, see below, which throws the following error:

"Invalid Cast Exception was Unhandled"
"Unable to cast object of type 'System.Data.DataRowView' to type 'TypedDataTableRow'."

I am puzzled by this error because the databound item is a "TypedDataTableRow". I appreciate the help of anyone who can get me past this error.

private void MyDataGridView_CellClick(object sender, DataGridViewCellEventArgs e)
            TypedDataTable.TypedDataTableRow row = (TypedDataTable.TypedDataTableRow) MyDataGridView.Rows[e.RowIndex].DataBoundItem;

Open in new window

Question by:mattjankowski
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
LVL 30

Assisted Solution

anarki_jimbel earned 1000 total points
ID: 24408349
try put brackets

TypedDataTable.TypedDataTableRow row = (TypedDataTable.TypedDataTableRow) (MyDataGridView.Rows[e.RowIndex].DataBoundItem);

Or might be :

TypedDataTable.TypedDataTableRow row = (TypedDataTable.TypedDataTableRow) (MyDataGridView.Rows[e.RowIndex]);

LVL 39

Expert Comment

ID: 24408401
From what I get about the the TypedDataTable is that it is merely a wrapper and under the hood simply holds a reference to a DataTable. When you bind the TypeDataTable to the DataGridView, you actually bind the DataTable. The DataTable will (MVC principle) bind in fact the DataView. Each row that is displayed is than essentially the DataRowView.

This DataRowView is castable to the original data type, in this case, the DataRow. Going from the DataRow back to a TypeDataTableRow should be something like a cast (but that didn't work) or a "new TypedDataTableRow". Since Microsoft has literally zero documentation on this object (they have on TypedDataTable, though, which is why I came up with my little "under the hood wrap-up") and since I cannot test it in the absence of BizTalk (is it part of some redistributable package? then I could play with it a little) I have to guess on this part.

Is it really necessary to have the original type back? It might not be there for the reasons I laid out in the first lines above...

-- Abel --
LVL 39

Assisted Solution

abel earned 1000 total points
ID: 24408410
hmm, on second thought, the second suggestion of anarki_jimbel (though without the second pair of parenthesis as the dot is higher in priority rank than the cast anyway) might be a good suggestion too ;-)
Fill in the form and get your FREE NFR key NOW!

Veeam® is happy to provide a FREE NFR server license to certified engineers, trainers, and bloggers.  It allows for the non‑production use of Veeam Agent for Microsoft Windows. This license is valid for five workstations and two servers.


Author Comment

ID: 24408509
anarki and Abel,

Thank you for your comments. I really appreciate you both taking the time to try to help me out:

Starting with anarki's suggestions:

I tried:
TypedDataTable.TypedDataTableRow row = (TypedDataTable.TypedDataTableRow)(MyDataGridView.Rows[e.RowIndex]);
And received this error at compile:
Error 5      Cannot convert type 'System.Windows.Forms.DataGridViewRow' to 'TypedDataTable.TypedDataTableRow'.

I also tried:
TypedDataTable.TypedDataTableRow row = (TypedDataTable.TypedDataTableRow) (MyDataGridView.Rows[e.RowIndex].DataBoundItem);

And received this error:
//Unable to cast object of type 'System.Data.DataRowView' to type 'EventLoggingRow'.

And, combining Abel's Comments with anarki's suggestions:
Attempt 3:
DataRow drow = (DataRow) MyDataGridView.Rows[e.RowIndex].DataBoundItem;
//Unable to cast object of type 'System.Data.DataRowView' to type 'System.Data.DataRow'.

Attempt 4:
DataRow drow = (DataRow) scribeDGV.Rows[e.RowIndex];
//Error     5       Cannot convert type 'System.Windows.Forms.DataGridViewRow' to 'System.Data.DataRow'  

To answer Abel's question: The original type is desired because not all the columns are bound to the DataGridView. I need to duplicate some of the elements in this row and create a new based on user input.

Thanks again for your help. No solution thus far. How can I make this process easier?

LVL 39

Expert Comment

ID: 24408533
On that last question, I can be short: just put a member variable to your form, set it to the datasource, wrap it in a property and call that when you set the DataSource to the grid and call it when you need a reference to the datasource like in the above event. Of course, the datatype of this property and the member type will be the TypeDataTable.

don't worry about having duplicate data (in case you were worrying, that is): in C#, basically in all OO languages, all that's stored is a reference to the table, the table itself is not copied.
LVL 39

Expert Comment

ID: 24408536
I am a bit surprised about your casting problems. Are you positive about the contents of the row you are clicking on? Is it perhaps a header row or a footer row? It should be possible to downcast the object...

The error message clearly states that the real type of the (otherwise typeless) DataSource property is really a DataRowView. And I cast that all the time....without complaints... :S

Author Comment

ID: 24408558
Hi Abel,

As far as wrapping the DataSource in a property, I see what you are saying, but not all of my DataSource is displayed in the DataGridView. The Row Index I obtain at cell click does not always correlate to the Data in the Datasource.

As to the contents of the row, in the debugger when I navigate to MyDataGridView.Rows[] I can actually see the source row from the typed DataTable.

Thanks for your comments, if you have more please keep them coming!


Accepted Solution

mattjankowski earned 0 total points
ID: 24408670
Abel and anarki:

I have a solution, but also a dilemma.

Here is the solution:
DataRowView dvrow = (DataRowView)MyDataGridView.Rows[e.RowIndex].DataBoundItem;
TypedDataTableRow typedRow = (TypedDataTableRow)dvrow.Row;

My approach: I took what I learned from our conversation and poked around the Visual Studio debugger. I followed the data and realized there were really a series of rows that I needed to cast. I may have been able to do this in one step, but I am quite happy to have it done at all.  

My dilemma. I believe that you both helped me come to this solution. Is it possible for me to award points to you both?

Thanks again for your help!

LVL 39

Expert Comment

ID: 24409592
> (TypedDataTableRow)dvrow.Row;

so stupid. I had been looking at these members because I remembered somehow it should be in there, only now I see that I had collapsed (hidden) the Properties in the help... That's what you get for working too long... lol

Glad you found it! As per the dilemma: no problem at all. Just click the "Accept Multiple Solutions" with one of the answers above. In the follow-up screen you will seen all the awardable comments and you can put in the amount you think each answer is worth. The total should add to the question total. The one comment you assign the highest will be considered "accepted solution", the others will be "assisted solution". The computer will choose in the event of a tie.

Note that the grade you give should be about the answers and/or the effort. It doesn't cost more points to assign higher grades. Just for your info, the two subjects causing the most confusion at EE: here are some closing tips and the 10pts must principle.

The screenshot is that other point of confusion to many: The red circle is for those cases where you found your solution yourself: it will select your comment as solution and you can then divide the points between the others. The green circle is what you're after.

Welcome at EE! ;-)

LVL 39

Expert Comment

ID: 24413319
Ah yes, you are right, in your case the red one was more applicable, apologies for appearing as if that would be the bad choice...

Featured Post

[Webinar] Lessons on Recovering from Petya

Skyport is working hard to help customers recover from recent attacks, like the Petya worm. This work has brought to light some important lessons. New malware attacks like this can take down your entire environment. Learn from others mistakes on how to prevent Petya like worms.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
This course is ideal for IT System Administrators working with VMware vSphere and its associated products in their company infrastructure. This course teaches you how to install and maintain this virtualization technology to store data, prevent vuln…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…

649 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question