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. 设计模式之观察者模式(Observer)(4)

    简介 观察者模式(Observer)完美的将观察者和被观察的对象分离开.举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上.面向对象设 ...

  2. POJ3268(KB4-D spfa)

    Silver Cow Party Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 23426   Accepted: 1069 ...

  3. BZOJ2956: 模积和(数论分块)

    题意 题目链接 Sol 啊啊这题好恶心啊,推的时候一堆细节qwq \(a \% i = a - \frac{a}{i} * i\) 把所有的都展开,直接分块.关键是那个\(i \not= j\)的地方 ...

  4. HTML(5)基础

    1.html常用标签 <pre>...</pre>:标识预定义文本 <a>是anchor的缩写,<a>标签定义锚点和超链接,<a>常与hre ...

  5. hadoop在zookeeper上的高可用HA

    (参考文章:https://www.linuxprobe.com/hadoop-high-available.html) 一.技术背景 影响HDFS集群不可用主要包括以下两种情况:一是NameNode ...

  6. [基础知识]PeopleSoft应用服务器上的进程含义

    1.PSAPPSRV PSAPPSRV作用是用来构建和报错HTML页面,运行peoplecode,处理消息和处理用户机器的sql请求.他还在用户机器最初登陆时候执行用户身份验证的任务. 2.PSSAM ...

  7. 你真的理解PeopleSoft的Web概要(web profile)嘛

    Web概要通过配置门户相关属性来控制门户的所有行为. 在PS系统中可以创建多个web概要,你可以通过不同的web概要来让用户路由到一个特定的web概要来控制超时,外观,缓存设置等.例如,通过Peopl ...

  8. HBuilder开发iPad程序不能全屏显示的解决方法

    HBuilder开发iPad程序不能全屏显示的解决方法: targets选择HBuilder=>Deployment Info=> devices选择Universal即可

  9. pm2以windows服务运行

    借助于pm2-windows-service 可以把pm2以windows服务运行.已服务运行的好处就是,即时用户注销也,pm2也会在后台运行 npm i pm2 -g npm i pm2-windo ...

  10. BBR,附CentOS 6/7配置过程

    最近这段时间BBR都比较火,前面有说如何在CAC的Debian-8-64bit安装BBR正确打开方式,现在说下,CentOS 6/7配置过程. 推荐理由:没配置BBR前,用SS看U2B的速度206K/ ...