Solved

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

Posted on 2009-05-17
10
2,214 Views
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.

Thanks!
private void MyDataGridView_CellClick(object sender, DataGridViewCellEventArgs e)

        {

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

        }

Open in new window

0
Comment
Question by:mattjankowski
  • 6
  • 3
10 Comments
 
LVL 29

Assisted Solution

by:anarki_jimbel
anarki_jimbel earned 250 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]);

0
 
LVL 39

Expert Comment

by:abel
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 --
0
 
LVL 39

Assisted Solution

by:abel
abel earned 250 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 ;-)
0
 

Author Comment

by:mattjankowski
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?

Thanks,
Matt
0
 
LVL 39

Expert Comment

by:abel
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.
0
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 
LVL 39

Expert Comment

by:abel
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
0
 

Author Comment

by:mattjankowski
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!

Matt
0
 

Accepted Solution

by:
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!

Matt
0
 
LVL 39

Expert Comment

by:abel
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! ;-)

ScreenShot270.png
0
 
LVL 39

Expert Comment

by:abel
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...
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
c# string handling 1 27
Problem of RegEx to match the first occurence of 10 36
Syntax Error 2 46
VB.NET 2008 Populate DataModel with DataTable 36 7
This document covers how to connect to SQL Server and browse its contents.  It is meant for those new to Visual Studio and/or working with Microsoft SQL Server.  It is not a guide to building SQL Server database connections in your code.  This is mo…
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 Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
In this video I am going to show you how to back up and restore Office 365 mailboxes using CodeTwo Backup for Office 365. Learn more about the tool used in this video here: http://www.codetwo.com/backup-for-office-365/ (http://www.codetwo.com/ba…

920 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now