是否有一种更简单的方法来颠倒DataGridViewSelectedRowCollection的顺序

本文关键字:方法 顺序 DataGridViewSelectedRowCollection 更简单 一种 是否 | 更新日期: 2023-09-27 18:11:07

由于某些奇怪的原因,DataGridViewSelectedRowCollection的填充顺序与DataGridView中显示的顺序相反。但更令人费解的是,为什么没有一种直接的方法来逆转foreach循环中使用的顺序。

我希望能够使用像这样简单的语法:

foreach (DataGridViewRow r in dataGridView1.SelectedRows.Reverse())

…当然,这是不支持的。*

所以,目前我使用的是这个怪物:

//reverse the default selection order:
IEnumerable<DataGridViewRow> properlyOrderedSelectedRows 
         = dataGridView1.SelectedRows.Cast<DataGridViewRow>().ToArray().Reverse();
foreach (DataGridViewRow r in properlyOrderedSelectedRows )
{
    MessageBox.Show( r.Cells["ID"].Value.ToString());
}

…这是非常丑陋和复杂的。(我意识到我可以使用反向For循环,但我更喜欢foreach的可读性。)

我在这里错过了什么?有没有更简单的方法?

*实际上,根据这里的讨论,我希望这个版本能够工作,因为DataGridViewSelectedRowCollection实现了IEnumerable;但是它不能编译

是否有一种更简单的方法来颠倒DataGridViewSelectedRowCollection的顺序

我认为你只需要在你的for循环中像这样强制转换:

  foreach (DataGridViewRow row in dataGridView1.SelectedRows.Cast<DataGridViewRow>().Reverse()) {
  }

然而,即使看起来代码更少,这也不是那么有效,因为它基本上必须通过枚举器向前将所有内容放入堆栈,然后以相反的顺序弹出所有内容。

如果你有一个可直接索引的集合,你绝对应该使用for循环,并以相反的顺序枚举该集合。

正如这里提到的可以通过foreach向后迭代吗?

您可以将行添加到堆栈中…

stack<DataGridViewRow> properlyOrderedSelectedRows  = new stack<DataGridViewRow>(dataGridView1.SelectedRows);
foreach (DataGridViewRow r in properlyOrderedSelectedRows )
{
    MessageBox.Show( r.Cells["ID"].Value.ToString());
}

Stack<T>有一个接受IEnumerable<T>的构造函数

但更令人困惑的是为什么没有一种直接的方法来反转foreach循环中的使用顺序。

我希望能够使用像这样简单的语法:

…当然,这是不支持的。*

不如你自己去做,而不是那些假的机智的陈述,"怪物"。和效率极低的linq。您所需要的只是在一些常见的地方编写一个单行函数。

public static IEnumerable<DataGridViewRow> GetSelectedRows(this DataGridView source)
{
    for (int i = source.SelectedRows.Count - 1; i >= 0; i--)
        yield return source.SelectedRows[i];
}