【问题标题】:DataGridView AddRange, Cast IEnumerable<object[]> to DataGridViewRow[] (If possible, using LINQ)DataGridView AddRange,将 IEnumerable<object[]> 转换为 DataGridViewRow[](如果可能,使用 LINQ)
【发布时间】:2016-01-12 04:28:21
【问题描述】:

如果我们想在DataGridView 中添加一行,除了添加一个DataGridViewRow 对象外,我们还可以通过传递一个对象数组来实现 (object[])

dgv.Rows.Add(objArray); //objArray is of type object[]

但是,如果我们想将一系列行添加到DataGridView,我们不能传递IEnumerable&lt;object[]&gt;,而只能传递DataGridViewRow[]

dgv.Rows.AddRange(ienumObjArray); //not allowed, ienumObjArray is of type IEnumerable<object[]>
dgv.Rows.AddRange(dgvRows); //allowed, dgvRows is DataGridViewRow[]

我的问题:有什么方法可以将 IEnumerable&lt;object[]&gt; 转换为 DataGridViewRow[](如果可能,使用 LINQ)以便我们可以做这样的事情

dgv.Rows.AddRange(ienumObjArray.DoSomethingWithLinq(x => doSomething)); 

并且不需要object[]一一添加?

foreach(object[] objArray in ienumObjArray)
    dgv.Rows.Add(objArray); //adding one by one, is it possible to get rid this of?

编辑:

这是在WinForms上完成的

编辑2:

应用@abatishchev 的建议(没有AddRange),我遇到了奇怪的结果。如果我说:

ienumObjArray.Select(objArr => dgv.Rows.Add(objArr)); 

var result = ienumObjArray.Select(objArr => dgv.Rows.Add(objArr)); 

然后,dgv 没有添加行。

但如果我做这些,

ienumObjArray.Select(objArr => dgv.Rows.Add(objArr)).ToArray();
ienumObjArray.Select(objArr => dgv.Rows.Add(objArr)).ToList();
ienumObjArray.Select(objArr => dgv.Rows.Add(objArr)).Count();

or 

var result = ienumObjArray.Select(objArr => dgv.Rows.Add(objArr))
foreach(int i in result){
    //do something
}

然后它工作正常!为什么会这样?

【问题讨论】:

  • ienumObjArray.Select(objArr =&gt; dgv.Rows.Add(objArr)).ToArray()?
  • @abatishchev 我试过了,但似乎我们不能这样添加dgv.Rows......太糟糕了:(.ToArray()返回int[]
  • Rows.Add() 返回添加的行数。所以返回的数组应该包含索引
  • 不客气!但是我个人会坚持使用 foreach 循环。我曾经更喜欢神秘的单线,但如果它是一个严肃的应用程序,我建议使用可读性和可维护性而不是小尺寸和花哨的外观。
  • 不错的选择!使用Select 调用的副作用不是一个好主意。当然,由于 LINQ 延迟执行,您会得到“奇怪的结果”,例如没有在前 2 个案例中执行。

标签: c# winforms linq datagridview rows


【解决方案1】:

作为一个选项,您可以将AddRange 扩展方法添加到接受IEnumerable&lt;object[]&gt; 作为参数的DataGridViewRowCollection

public static class DataGridViewExtensions
{
    public static void AddRange(this DataGridViewRowCollection collection, IEnumerable<object[]> rows)
    {
        foreach (object[] item in rows)
        {
            collection.Add(item);
        }
    }
}

有关扩展方法的更多信息:

【讨论】:

  • 我明白了,你实际上是在创建一个从DataGridView 派生的新class --> public static class DataGridViewExtensions : DataGridView 这就是你的意思吗?我的意思是,该类的名称实际上是否保持为DataGridView
  • 不,是扩展方式。它实际上扩展了DataGridViewRowCollection 类并将AddRange(IEnumerable&lt;object[]&gt; rows) 添加到它。
  • 哇!但是你把class放在哪里?
  • 扩展方法使您能够将方法“添加”到现有类型,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。扩展方法是一种特殊的静态方法,但它们被称为扩展类型的实例方法。对于用 C# 和 Visual Basic 编写的客户端代码,调用扩展方法和实际定义在类型中的方法之间没有明显区别。
  • 把类放到你项目的某个地方。和其他普通班一样。只需确保以您想要调用它的形式在using 部分中使用它的命名空间。
【解决方案2】:

在这里,我们可以使用带有IEnumerable&lt;object[]&gt; 的linq 创建DataGridViewRow 的列表,因此我们可以使用DataGridViewRowCollectionAddRange,因此在它调用该方法之前。尝试选择一个新的DataGridViewRow 看看:

dgv.Rows.AddRange(ienumObjArray.Select(cols => PrepareDataGridViewRow(dgv,cols)).ToArray());

.

private static DataGridViewRow PrepareDataGridViewRow(DataGridView dgv, object[] cols)
{
    var result = new DataGridViewRow();
    result.CreateCells(dgv,cols);
    return result;
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-30
    • 1970-01-01
    • 1970-01-01
    • 2017-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多