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虚拟机 - Class类文件结构

    [深入Java虚拟机]之二:Class类文件结构 平台无关性 Java是与平台无关的语言,这得益于Java源代码编译后生成的存储字节码的文件,即Class文件,以及Java虚拟机的实现.不仅使用Jav ...

  2. java 非阻塞算法实现基础:unsafe类介绍

    一.为什么要有Unsfae.我们为什么要了解这个类 1. java通常的代码无法直接使用操作底层的硬件,为了使java具备该能力,增加了Unsafe类 2.java的并发包中底层大量的使用这个类的功能 ...

  3. C#转换成Json的方法集

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Te ...

  4. hadoop学习之yarn资源管理

    一.yarn简介 yarn是在hadoop2.x中才引入的一个新的机制,在hadoop1.x中MapReduce任务需要同时做任务管理和资源分配,那么引入yarn之后,hadoop的资源管理的任务就全 ...

  5. NIO学习笔记六:channel 之前数据传输及scatter/gather

    在Java NIO中,如果两个通道中有一个是FileChannel,那你可以直接将数据从一个channel传输到另外一个channel. FileChannel的transferFrom()方法可以将 ...

  6. Vue.js之路由系统

    Vue.js生态之vue-router vue-router是什么? vue-router是Vue的路由系统,定位资源的,我们可以不进行整页刷新去切换页面内容. vue-router的安装与基本配置 ...

  7. 【读书笔记】iOS-应用程序剖析

    一,Default.png 包含应用程序默认扉页的PNG图像文件.用户运行应用程序时,iPhone会用此图片显示一个动画,产生由小变大来到屏幕前的效果.应用程序的Default.png文件加载后会不断 ...

  8. drupal7创建自定义的panels布局

    很简单,在主题的 *.info文件中添加一句代码: 这一句很简单,但也很重要,没有这一句,就没在panels的配置界面去显示自定义的布局 plugins[panels][layouts] = layo ...

  9. 浅谈http协议六种请求方法,get、head、put、delete、post、options区别

    标准Http协议支持六种请求方法,即: 1.GET 2.POST 3.PUT 4.Delete 5.HEAD 6.Options 但其实我们大部分情况下只用到了GET和POST.如果想设计一个符合RE ...

  10. hudson运行出现java.io.IOException Cannot run program的错误分析

    作者:朱金灿 来源:http://blog.csdn.net/clever101 在昨天运行每日构建时hudson突然出错,错误信息如下: [MySoft3.1] $ cmd /c call &quo ...