获取当前显示顺序下选定的DataGridView行

6

我有一个包含三个不同的DataColumns的未绑定数据的DataGridView。每列都可以进行排序,但除此之外,不能对显示的数据进行任何操作。

当我查询SelectedRows属性时,行按照我最初插入它们的顺序排序,而不是按照当前显示或选择的顺序排序。有没有办法改变这种行为?

6个回答

10

我有相同的问题。 看起来这是最短的方法:

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

是的,这确实是获取所选行排序的最短和最佳方法。+1。谢谢。 - SajuPK

6

SelectedRows属性包含选定的行,但顺序相反,最近的项目位于列表的开头。要获取正确的用户选择顺序,请执行以下代码:

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;
}

注意:无需排序。

2
以下是上述代码的VB.NET版本。

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()

C# 到 VB.NET 的转换器无法正确翻译这个。希望这可以帮助任何希望使用此功能的 VB.NET 程序员。 Paul

请确保导入 System.Linq。 - nh32rg

2

我认为没有一种单行的方法来完成这个任务。你需要重新对列表进行排序,然后使用IndexOf和SelectedItems来确定视觉位置。

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);
}

请注意,上述内容尚未经过编译测试,可能需要进行一些微调。

1
如果你反转生成的列表,它就能工作。 - xsl
我想可能是这样的 - 我已经交换了 return...CompareTo 行。谢谢你让我知道。 - Greg Sansom

0

你应该可以像这样引用所选单元格中的值:

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

0

所选单元格似乎是按点击顺序或至少是相反的顺序。这个尽可能简单地工作:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接