views:

25

answers:

2

Hi,

I have a DataGrid containing a small table. Until now, I had a double click handler on this grid which iterated over all rows to find the selected one:

DataTable table = (DataTable)this.dataGrid.DataSource;
int selectedRow = -1;
for (int i=0; i<table.Rows.Count; i++)
  if (this.dataGrid.IsSelected(i))
    selectedRow = i;
    break;
  }
if ( selectedRow != -1 ) {
  DataRow row = table.Rows[selectedRow];
  // More code ...
}

Problem: When the user clicks on a column header and sort the table, table.Rows does not return the right rows. It still contains the unsorted rows.

How can I get the right column?

Edit 1: I have a System.Windows.Forms.DataGrid, not a DataGridView. I don't know the difference, because I don't know .Net very much. Can I simply replace DataGrid with DataGridView?

+1  A: 

Why not use DataGridView.SelectedRows property? Then use DataBoundItem for those rows to access underlying data. This may be of type DataRowView. In that case, use the DataRowView.Row property.

foreach (DataGridViewRow dgvrow in dataGrid.SelectedRows)
{
  DataRow row = null;
  if (dgvrow.DataBoundItem is DataRowView)
    row = (dgvrow.DataBoundItem as DataRowView).Row as DataRow;
  else
    row = dgvrow.DataBoundItem as DataRow;

  // ... stuff
}
Thorsten Dittmar
Huh? What's wrong with my code sample?
Thorsten Dittmar
@Thorsten Dittmar: Since the question was changed to `DataGrid` control, your code is not relative, so it makes no difference if I feel there is something odd about the code. :O)
AMissico
I didn't realize he was talking about DataGrid now :-D
Thorsten Dittmar
Yeah, he got me also. :O) Thank goodness I still support a .NET 1.1 application, so had the code ready.
AMissico
+1  A: 

DataGrid (Windows)

Try DataGrid.GetSelectedDataRows below, where MyBase is the name of your DataGrid.

    Public Function GetSelectedDataRows() As DataRow()
        Dim oSelectedRows As New ArrayList
        Dim oDataTable As DataTable = DirectCast(MyBase.DataSource, DataTable)
        For i As Integer = 0 To oDataTable.Rows.Count - 1
            If MyBase.IsSelected(i) Then
                oSelectedRows.Add(oDataTable.DefaultView(i).Row)
            End If
        Next
        Return DirectCast(oSelectedRows.ToArray(GetType(DataRow)), DataRow())
    End Function

DataGridView

Use the SelectedRows property. It returns the collection of DataGridViewRow objects. Since you know you are binding a DataTable, the DataGridViewRow.DataBoundItem property will be a DataRow. Check the above object help topics for examples.

References

Excerpts

The DataGrid control is retained for backward compatibility and for special needs. For nearly all purposes, you should use the DataGridView control. The only feature that is available in the DataGrid control that is not available in the DataGridView control is the hierarchical display of information from two related tables in a single control. You must use two DataGridView controls to display information from two tables that are in a master/detail relationship.

AMissico
Yes, as I said. Could you specify what's wrong with my code sample? I don't see what shouldn't "seem right"...
Thorsten Dittmar