【问题标题】:is there an easier way to reverse the order of a DataGridViewSelectedRowCollection?有没有更简单的方法来反转 DataGridViewSelectedRowCollection 的顺序?
【发布时间】:2015-11-29 13:12:40
【问题描述】:

出于某种奇怪的原因,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 的可读性。)

我在这里缺少什么?有没有更简单的方法?

*实际上,根据discussion here,我本来希望这个版本可以工作,因为DataGridViewSelectedRowCollection implements IEnumerable;但它没有编译。

【问题讨论】:

  • 你能把它们按相反的顺序写出来吗?从数组的末尾循环到开头?避免调用全部反转?
  • @SamPlusPlus:我想使用foreach 循环,如上所述。
  • 在您的限制下(老实说,我不太清楚;就我个人而言,我会依赖反向 for 循环)您的方法似乎很好(您可以通过删除正确的OrderedSelectedRows 和在 foreach 循环中添加整个反转)。至少,假设 SelectedRows 总是以完全相反的顺序提供;否则你将不得不依赖 OrderBy by row index。

标签: c# winforms collections datagridview


【解决方案1】:

我认为你只需要在你的 for each 循环中添加:

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

  }

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

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

这里提到Possible to iterate backwards through a foreach?

【讨论】:

  • 我知道效率的权衡,但我并不十分担心它。这是一个 SelectedRowCollection,当用户选择了很多行时,这种情况很少见。但是你确实将我的方法链减少了一个,至少,所以你赢得了奖品。谢谢。
【解决方案2】:

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

stack<DataGridViewRow> properlyOrderedSelectedRows  = new stack<DataGridViewRow>(dataGridView1.SelectedRows);

foreach (DataGridViewRow r in properlyOrderedSelectedRows )
{
    MessageBox.Show( r.Cells["ID"].Value.ToString());
}

Stack&lt;T&gt; 有一个constructor 接受IEnumerable&lt;T&gt;

【讨论】:

    【解决方案3】:

    但更令人费解的是,为什么没有一种直接的方法可以颠倒在 foreach 循环中使用的顺序。

    我希望能够使用这样简单的语法:
    ...
    ...但当然,这是不支持的。*

    如何让它自己工作,而不是所有这些伪诙谐的陈述、“怪物”和效率极低的 LINQ-es。您只需要在某个常见的地方编写一个单行函数即可。

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

    【讨论】:

    • 嗯,这是您的解决方案的 +1; -1 对我的写作风格的无益批评。
    • 会发生什么...会发生
    猜你喜欢
    • 1970-01-01
    • 2021-10-14
    • 1970-01-01
    • 2012-10-25
    • 2015-04-15
    • 2012-01-11
    • 1970-01-01
    • 1970-01-01
    • 2017-12-18
    相关资源
    最近更新 更多