How to get selected records from a DataGridView to a DataTable?

marksquall

Active member
Joined
Oct 17, 2009
Messages
28
Programming Experience
3-5
Hello guys,

I hope everyone is in good health upon reading this forum.

I am creating my own search engine in VB .NET (2010) for my database of Marvel Superheroes (I am using SQL Server 2008), searching for names, powers, etc. Though still on improving, the search is working fine on names and the result/s is/are displayed in DataGridView.

If I search for names, and I get ten (10) results, I just want to ask how to transfer a certain record (let's say record number 8) to a DataTable. They say that I should put first a certain record from DataGridView to a DataTable, and use that object (of type DataTable) as a data source in a crystal report. (which is I am still working on).

I hope someone could help me with this one...

Thank you and more power.:tennis:


Respectfully Yours,

Mark Squall:)
 
E.g.
For Each row As DataGridViewRow In myDataGridView.Rows
    myDataTable.Rows.Add(row.Cell(0).Value, row.Cells(1).Value)
Next
 
You can also just cast the bound item (assuming you are using a binding source) to a DataRow like this:

For Each row As DataGridViewRow In myDataGridView.Rows
    myDataTable.Rows.Add(TryCast(row.DataBoundItem, DataRow))
Next


This is also a bit safer and faster as an invalid cast does not throw an exception you would otherwise have to catch, TryCast just returns nothing on invalid cast.
 
You can also just cast the bound item (assuming you are using a binding source) to a DataRow like this:

For Each row As DataGridViewRow In myDataGridView.Rows
    myDataTable.Rows.Add(TryCast(row.DataBoundItem, DataRow))
Next


This is also a bit safer and faster as an invalid cast does not throw an exception you would otherwise have to catch, TryCast just returns nothing on invalid cast.

If you bind a DataTable then the data comes from its DefaultView, so each item is actually a DataRowView, not a DataRow. Also, why would you want to pass a null reference to that Add method? Are you sure that that won't throw an exception? My guess is that it would throw an ArgumentNullException, which I just confirmed by reading the MSDN documentation. The proper way to use TryCast is to assign the result to a variable and then test that variable using a If statement, only using it if it is not a null reference.
 
Oops you are right, slight typo.

For Each row As DataGridViewRow In myDataGridView.Rows
    myDataTable.ImportRow(TryCast(row.DataBoundItem, DataRowView).Row)
Next


The particular exception I was was talking about was the InvalidCastException from the casting itself, you are right about the ArgumentNullException, the row should be checked before adding to the datatable, or the exception should be trapped. In any case it should not really matter since a bad conversion should not happen in the first place, as the DataGridViewRow is already being tested against Nothing via the for each loop. Also testing the row against Nothing is far less performance heavy than trapping an exception.

In this case it really would make no difference using DirectCast, CType or TryCast... DirectCast might be a bit faster.

EDIT: After further testing all three methods of casting have the exact same speed as far as I can discern, at least for copying 1 million rows. The first copy takes the longest (~1 minute), following ones are cached (around 2 seconds). Copying the field values is significantly longer (around 4 minutes over a million 4-bytes x 10 fields records in the datagridview). Also corrected the method used, ImportRow actually has to be used since the original row is already part of a datatable.
 
Last edited:
Oops you are right, slight typo.

For Each row As DataGridViewRow In myDataGridView.Rows
    myDataTable.Rows.Add(TryCast(row.DataBoundItem, DataRowView).Row)
Next


The particular exception I was was talking about was the InvalidCastException from the casting itself, you are right about the ArgumentNullException, the row should be checked before adding to the datatable, or the exception should be trapped. In any case it should not really matter since a bad conversion should not happen in the first place, as the DataGridViewRow is already being tested against Nothing via the for each loop. Also testing the row against Nothing is far less performance heavy than trapping an exception.

In this case it really would make no difference using DirectCast, CType or TryCast... DirectCast might be a bit faster.

That code still won't work because you can't add a DataRow to a DataTable other than the one that created it. You'd have to call ImportRow.
 
Back
Top