xsl
xsl

Reputation: 17406

Get selected DataGridViewRows in currently displayed order

I have a DataGridView with unbound data that contains three different DataColumns. The rows can be sorted by each column, but other than that no manipulation of the displayed data is allowed.

When I query the SelectedRows property the rows are sorted in the order I initially inserted them, and not like I expected in the currently displayed or selected order. Is there a way to change this behavior?

Upvotes: 6

Views: 10522

Answers (7)

Cannon777
Cannon777

Reputation: 1

Or else:

        List<DataGridViewRow> rows =
        [
            .. (from DataGridViewRow row in dgv.SelectedRows
                where !row.IsNewRow
                orderby row.Cells["some_column"].Value.ToString() ascending
            select row),
        ];

        foreach (DataGridViewRow dr in rows)
        {
        ...
        }

Upvotes: 0

General Failure
General Failure

Reputation: 141

SelectedCells seem to be in click order or at least reverse. This one works as simple as possible:

foreach (DataGridViewRow row in dataGridLog.Rows)
{
    foreach (DataGridViewCell cell in row.Cells)
    {
        if (cell.Selected)
            sb.AppendLine($"{cell.Value.ToString()}");
    }
}

Upvotes: 0

Paul Smith
Paul Smith

Reputation: 51

here is the vb.net version of the above code.

C#

List<DataGridViewRow> rows = 
    (from DataGridViewRow row in dgv.SelectedRows 
    where !row.IsNewRow 
    orderby row.Index 
    select row).ToList<DataGridViewRow>();

VB.NET

Dim rows As List(Of DataGridViewRow) = (From row As DataGridViewRow 
   In dgv.SelectedRows Where Not row.IsNewRow Order By row.Index).ToList()

The C# to VB.NET converters do not translate this correctly.

Hope this helps any VB.NET coder wishing to use this.

Paul

Upvotes: 2

esc
esc

Reputation: 228

I have same problem. Its look the shortest way:

List<DataGridViewRow> rows = 
    (from DataGridViewRow row in dgv.SelectedRows 
    where !row.IsNewRow 
    orderby row.Index 
    select row).ToList<DataGridViewRow>();

Upvotes: 10

mas_oz2k1
mas_oz2k1

Reputation: 2901

The SelectedRows property contains the selected rows but in the reverse order and the most recent item is at the start of the list. To get the correct user selected order do the following code:

List<DataGridViewRow> dgList = new List<DataGridViewRow>();
foreach (DataGridViewRow r in dgv.SelectedRows)
{
    dgList.Insert(0, r);
}
foreach(DataGridViewRow r in dgList)
{
   //Print/consume your row here.
   int selectedIndex = r.Index;
}

Note: No need to sort.

Upvotes: 6

Greg Sansom
Greg Sansom

Reputation: 20820

I don't think there's a one-line way to do this. You will need to redo the sort into your own list, then use IndexOf with the SelectedItems to find out the visual position.

List<DataGridViewRow> l = new List<DataGridViewRow>();
foreach (DataGridViewRow r in dgv.Rows)
{
    l.Add(r);
}

l.Sort((x, y) =>
    {
        IComparable yComparable = (IComparable)x.Cells[dgv.SortedColumn.Index].Value;
        IComparable yc = (IComparable)x.Cells[dgv.SortedColumn.Index].Value;

        if (dgv.SortOrder == SortOrder.Ascending)
            return yc.CompareTo(yComparable);
        else
            return yComparable.CompareTo(yc);
    }
    );

foreach(DataGridViewRow r in dgv.SelectedRows)
{
    int selectedIndex = l.IndexOf(r);
}

Note the above has not been compile tested and might need some tweaking.

Upvotes: 2

Beth
Beth

Reputation: 9607

You should be able to refer to the values in the selected cell like this:

Private Sub determinePKVals(ByRef PKVal As String, ByRef PKVal2 As String, Optional ByVal row As Integer = -1)
    If row = -1 Then        ' optional value not passed
        row = dgvDisplaySet.CurrentRow.Index
    End If

    PKVal = dgvDisplaySet.Rows(row).Cells(0).Value
    PKVal2 = dgvDisplaySet.Rows(row).Cells(1).Value
End Sub

Upvotes: 0

Related Questions