DataGridView对象是我们在进行Winform程序开发中经常使用的呈现数据的控件,而数据则是通过DataSource这个Property来设置的。根据MSDN的说明,DataGridView对象支持标准的Windows窗体数据绑定模型,任何实现了下面几种接口的对象都可以作为其数据源:

  • IList接口,包括一维数组。
  • IListSource接口,比如DataTable,DataSet类。
  • IBindingList接口,比如BindingList<T>类。
  • IBindingListView接口,比如BindingSource类。

DataTable对象通常被用来作为数据源直接绑定到Grid控件上,比如,

DataTable dtEmployees = new DataTable();
dataGridView1.DataSource = dtEmployees;

有的时候我们需要选择出表中的部分行作为数据源,当然我们可以通过设置DataTable的DefaultView属性过滤给定条件的记录,

DataTable gridTable = (DataTable) dataGrid1.DataSource;

// Set the RowFilter to display a company names that
// begin with A through I..
gridTable.DefaultView.RowFilter = "Age < 30";

但是,有的时候我们会用DataTable.Select方法提取出给定条件的DataRow集合数组,如果想直接把这个List<DataRow>作为数据源,最终会呈现几列没有意义的数据(RowError, RowState, Table, and HasErrors)。

实际上,我们也无法将一个IEnumerable<T>对象(比如,一个LINQ查询)作为数据源。 LINQ查询, 必须调用.ToList(). 或.ToArray()方法将其转换成非泛型的对象。

为什么无法将List<DataRow>对象作为数据源呢?

Databinding is controlled by the ListBindingHelper and TypeDescriptor classes.  When you bind to a list, the ListBindingHelper.GetListItemProperties method is called to get the columns in the list.  If the list implements the ITypedList interface, its GetItemProperties  method is called.  Otherwise, it will use TypeDescriptor to get the properties of the first item in the list.  (this uses reflection)

The DataView class (which DataTable also binds through, using IListSource) implements ITypedList and returns DataColumnPropertyDescriptors that expose the columns in the table.  This is why you can bind to a DataView or DataTable and see columns.  However, when you bind to a List<DataRow>, there is no ITypedList that can return the columns as properties.  It therefore falls back on reflection and shows the physical properties of the DataRow class.

上面是一位大人的解释,http://blog.slaks.net/2011/01/binding-to-lists-of-datarows.html/

他给的解决方案是,将List<DataRow>封装在一个实现了ITypedList接口的DataView类对象里。

To solve this issue, you need to wrap the list in a DataView so that you can take advantage of its ITypedList implementation.  You can do that using the AsDataView() method.  This method is only available on the DataTable  and EnumerableRowCollection<T> classes; it cannot be called on an arbitrary LINQ query.  You can only get an EnumerableRowCollection<T> by calling special versions of the Cast, OrderBy, Where, and Select methods from a DataTable.

我们直接看例子,

DataTable dtEmployee = buildMockTable();
DataRow[] drEmployees = dtEmployee.Select("emp_age <= 50"); List<DataRow> list = drEmployees.ToList<DataRow>();
dgvEmployees.DataSource = dtEmployee.AsEnumerable().Where(list.Contains).AsDataView();
// dgvEmployees.DataSource = dtEmployee.AsEnumerable().CopyToDataTable();

当然也可以调用CopyToDataTable方法,但这样会深拷贝所有的DataRow, 所以如果想更新数据或向让用户看到原始数据上的变化时就比较麻烦。

还有一种方法就是将List<DataRow>加到一个新的表里面,然后将这个表作为绑定数据源。

DataTable dtEmployee = buildMockTable();
DataRow[] drEmployees = dtEmployee.Select("emp_age > 50"); DataTable filteredTable = new DataTable("Employee");
filteredTable = dtEmployee.Copy();
filteredTable.Rows.Clear(); foreach (DataRow row in drEmployees)
{
filteredTable.ImportRow(row);
}
filteredTable.AcceptChanges();
dgvEmployees.DataSource = filteredTable.DefaultView;

这种方法类似CopyToDataTable

Source Code: DataSourceWithDataRow

References

DataGridView如何绑定DataRow对象集合的更多相关文章

  1. 基于.net的分布式系统限流组件 C# DataGridView绑定List对象时,利用BindingList来实现增删查改 .net中ThreadPool与Task的认识总结 C# 排序技术研究与对比 基于.net的通用内存缓存模型组件 Scala学习笔记:重要语法特性

    基于.net的分布式系统限流组件   在互联网应用中,流量洪峰是常有的事情.在应对流量洪峰时,通用的处理模式一般有排队.限流,这样可以非常直接有效的保护系统,防止系统被打爆.另外,通过限流技术手段,可 ...

  2. 【转】给DataTable和DataRow扩展方法,直接转换为对象集合或对象

    /// <summary> /// 类 说 明:给DataTable和DataRow扩展方法,直接转换为对象集合或对象 /// 补充说明:此扩展类可以极大的简化操作,但是性能低下,大数据以 ...

  3. 再谈使用Emit把Datatable转换为对象集合(List<T>)

    一.前因和存在的问题 前面我写了一篇<使用Emit把Datatable转换为对象集合(List<T>)>的博文,其实起源于我自己编写的一个orm工具(见前面几篇博文有介绍),里 ...

  4. 使用Emit把Datatable转换为对象集合(List<T>)

    Emit生成动态方法部分摘自网上,但是经过修改,加入了对委托的缓存以及类结构的调整,使之调用更简洁方便.大致的思路是:要实现转换datatable到某个指定对象的集合,本质是实现转换一个datarow ...

  5. ASP.NET Core的配置(3): 将配置绑定为对象[上篇]

    出于编程上的便利,我们通常不会直接利用ConfigurationBuilder创建的Configuration对象读取某个单一配置项的值,而是倾向于将一组相关的配置绑定为一个对象,我们将后者称为Opt ...

  6. ItemArray DataRow对象的RowState和DataRowVersion属性特点

    DataTable.Rows[i].ItemArray DataTable.Rows表示所有行的集合DataTable.Rows[i]加上下标表示其中某一行DataTable.Rows[i].Item ...

  7. [ASP.NET Core 3框架揭秘] 配置[4]:将配置绑定为对象

    虽然应用程序可以直接利用通过IConfigurationBuilder对象创建的IConfiguration对象来提取配置数据,但是我们更倾向于将其转换成一个POCO对象,以面向对象的方式来使用配置, ...

  8. ASP.NET Core的配置(3): 将配置绑定为对象[下篇]

    我们在<读取配置信息>通过实例的形式演示了如何利用Options模型以依赖注入的方式直接获取由指定配置节绑定生成的Options对象,我们再次回顾一下当初我们编写的程序.如下面的代码片段所 ...

  9. C#中对象,字符串,dataTable、DataReader、DataSet,对象集合转换成Json字符串方法。

    C#中对象,字符串,dataTable.DataReader.DataSet,对象集合转换成Json字符串方法. public class ConvertJson { #region 私有方法 /// ...

随机推荐

  1. JAVA动态代理基础

    Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM) 彻底理解JAVA动态代理 class文件简介及加载 Java编译器编译好Java文件之后,产生.class 文件在磁盘中. ...

  2. Java - "JUC" CyclicBarrier源码分析

    Java多线程系列--“JUC锁”10之 CyclicBarrier原理和示例 CyclicBarrier简介 CyclicBarrier是一个同步辅助类,允许一组线程互相等待,直到到达某个公共屏障点 ...

  3. ubuntu 18.04 设置固定ip

    # This file is generated from information provided by # the datasource.  Changes to it will not pers ...

  4. PHP 协程最简洁的讲解

    协程,又称微线程,纤程.英文名Coroutine.协程的概念很早就提出来了,但直到最近几年才在某些语言(如Lua)中得到广泛应用. 子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在执 ...

  5. 基于react的标准form+table页面的请求流程图

    componentDidMount直接走handleSearch而不走loadData,是为了当form有默认初始值的时候也能适用! --------------------2018.2.7新增--- ...

  6. JS--我发现,原来你是这样的JS(三)(基础概念--灵魂篇)

    一.介绍 这是红宝书(JavaScript高级程序设计 3版)的读书笔记第三篇(灵魂篇介绍),有着剩下的第三章的知识内容. 红宝书这本书可以说是难啃的,要看完不容易,挺厚的,要看懂更不容易,要熟练js ...

  7. linux下opencv编译

    .tar.gz cd opencv-/ cd .. mkdir my_build_dir cd my_build_dir cmake ../opencv- -DWITH_GTK_2_X=ON -DCM ...

  8. CSS3新特性,兼容性,兼容方法总结

    css3手册css3手册 边框 border-radius 用于添加圆角效果 语法: border-radius:[ <length> | <percentage> ]{1,4 ...

  9. ORACLE-SQL微妙之处

    本文总结一下平时经常使用的SQL语句以及一些ORACLE函数的微妙之处.欢迎大家多多补充平时最常用的SQL语句,供大家学习参考. SQL> select * from temp2; NAME S ...

  10. Oracle EBS OPM 事务处理

    --事务处理 --created by jenrry DECLARE l_iface_rec inv.mtl_transactions_interface%ROWTYPE; l_iface_lot_r ...