学习C#语言的朋友们肯定或多或少地接触到了WinForm编程,在C#语言的可视化IDE中(如VS.NET中)使用设计器可以让我们轻松地完成窗体、按钮、标签、图片框等等控件的组合,我们可以轻易地做出界面友好的WinForm应用程序。我们还可以通过WinForm程序中强大的事件处理机制来使我们的应用程序更加丰满。

  当然,我们这次不谈窗体、不谈按钮……

  我们谈谈DataGridView(数据网格视图)。

  作为真正与用户进行信息交互的界面,很大程度上需要向用户完整地展示数据,而在WinForm相关的强大控件中就有用于数据显示的。数量很多,但作为列表视图显示的控件,首推ListView和DataGridView。在显示多行多列的数据时,两者往往可以互相替换。

  由于笔者认为DataGridView的界面不如ListView友好,所以是尽量使用ListView而非DataGridView的,而最近却喜欢使用DataGridView了,主要原因当属它强大的数据处理。

  它可以智能处理绑定到的数据源,而且可作为数据源绑定的类型也非常之多。

  DataGridView 类支持标准的 Windows 窗体数据绑定模型。 这意味着数据源可以是实现下列接口之一的任何类型: 
  IList 接口,包括一维数组。 
  IListSource 接口,例如,DataTable 和 DataSet 类。 
  IBindingList 接口,例如,BindingList(Of T) 类。 
  IBindingListView 接口,例如,BindingSource 类。

  详情请参见 http://msdn.microsoft.com/zh-cn/library/system.windows.forms.datagridview.datasource.aspx(DataGridView.DataSource 属性)

  对于我们平时的编程来讲,可能将DataTable和List<T>绑定到DataGridView的DataSource是比较多的情况。

  但其实我想说的一点是(个人观点,不保证正确,真的):如果是DataTable,最好用DataTable的DataView;如果是IList<T>,最好用BindingList <T>。

  首先我们看看DataGridView里的重要属性:

  ①AutoGenerateColumns 属性(请参见http://msdn.microsoft.com/zh-cn/library/system.windows.forms.datagridview.autogeneratecolumns.aspx)

  这个属性十分重要,重要的原因之一:在VS的设计器属性里找不到(不知道为什么它会被加上不出现在属性列表里的特性……)。这个属性的作用很简单也很重要:指定DataGridView是否自动增加列。

  如果您希望通过手动添加列指定将要显示到数据网格视图绑定对象的属性,您必须将此属性设置为true;

  比如下面的例子:

  我希望在数据网格视图内显示自定义对象“员工的信息”:

  员工类:

 1 using System;
2
3 namespace dgvEG
4 {
5 // 员工类
6 public class SE : ICloneable
7 {
8 // 员工信息
9 public string Name { get; set; }
10 public int Age { get; set; }
11 public int WorkNo { get; set; }
12 public Gender Sex { get; set; }
13 public SignRecord Record { get; set; }
14
15 // 构造方法
16 public SE() { }
17
18 public SE(int workNo, string name, int age, Gender sex)
19 {
20 this.WorkNo = workNo;
21 this.Name = name;
22 this.Age = age;
23 this.Sex = sex;
24 this.Record = new SignRecord();
25 }

  表示性别的枚举:

 1 using System;
2
3 namespace dgvEG
4 {
5 /// <summary>
6    /// 性别
7    /// </summary>
8 public enum Gender
9 {
10 Male = 0, // 男
11 Female = 1 // 女
12 }
13 }

  员工的带卡记录(即签到签退的记录):

 1 using System;
2
3 namespace dgvEG
4 {
5 /// <summary>
6    /// 打卡记录
7    /// </summary>
8 public class SignRecord
9 {
10 // 签到时间
11 public DateTime SignInTime { get; set; }
12 // 签退时间
13 public DateTime SignOutTime { get; set; }
14 }
15 }

  如果我直接将“员工对象”的集合座作为数据源绑定到DataGridView的DataSource,并且也没有在DataGridView上进行任何过滤的操作,那么结果将是如此:

  

  上图有几点问题,我们一个个地来解决,首先是列名,我们肯定希望是中文的,如此,我们就需要手动指定列名。

  如果您使用VS作为开发工具,可以参考我的做法:

  

  这样是不是行了呢?我们再次运行程序,却得到下面的结果:

  

  ……估计没人愿意这样,我们再回到绑定数据源的代码:

 1         // 定义测试数据
2 SE se1 = new SE(10001, "测试1号", 19, Gender.Female);
3 SE se2 = new SE(10002, "测试2号", 20, Gender.Male);
4 SE se3 = new SE(10003, "测试3号", 21, Gender.Female);
5 SE se4 = new SE(10004, "测试4号", 22, Gender.Male);
6 SE se5 = new SE(10005, "测试5号", 23, Gender.Female);
7 SE se6 = new SE(10006, "测试6号", 24, Gender.Male);
8
9 // 利用测试数据制作数据源
10 List<SE> list = new List<SE>();
11 list.AddRange(new SE[] { se1, se2, se3, se4, se5, se6 });
12
13 // 绑定数据源
14 dataGridView1.DataSource = new BindingList<SE>(list);

  看起来没什么问题,这段代码可以放到例如窗体加载事件里正确执行。

  从上面的图片不难看出:我们手动添加的列是固有的,只是由于DataGridView对数据源的强大处理,它会自动添加列以正常且完整地显示数据源的信息。

  那么我们不让它自动增加列不就OK了?

  在绑定数据源之前加上一句代码,如下:

1             // ……
2        // ……
3        // 指定数据网格视图不自动增加列
4 dataGridView1.AutoGenerateColumns = false;
5 // 绑定数据源
6 dataGridView1.DataSource = new BindingList<SE>(list);

  不出所料,您看到的结果会是下图:

  

  请您不要急,仔细看看,项数是正确的!说明数据是没问题的,问题在我们希望用自己的方式显示数据,那么DataGridView的自动分析数据就不会执行,我们就必须指定哪一行显示对象的那一个属性。接下的第二个重要属性就是如此的作用:

  ②DataPropertyName属性(请参见http://msdn.microsoft.com/zh-cn/library/system.windows.forms.datagridviewcolumn.datapropertyname.aspx)

  值得注意的是:这个属性是DataGridView的列所拥有的,非DataGridView本身。故名思意,就是用来指定DataGridView中哪一列显示数据源对象的哪一个属性。您可以通过VS的设计器方便地进行这个属性的设置,如下图:

  

  进行了如上图的设置,我们就能得到如下图的正确结果了:

  

  同样的,在将数据表绑定到DataGridView时也可以如此操作。

  现在,我们试着增加难度,将员工对应打卡记录的签到信息显示出来。不少会举一反三的朋友可能会进行如下操作:

  

  事实证明,这样是不行的……

  这种做法是不被支持的。

  另外一个问题其实我们也希望一并解决:性别,我们肯定希望是显示中文的男和女。怎么做呢?其实有一个事件可以做:

  ③RowsAdded 事件(参见http://msdn.microsoft.com/zh-cn/library/system.windows.forms.datagridview.rowsadded(VS.80).aspx)(不保证有更简易的做法)

  这个事件是当当前DataGridView中添加一行或多行数据时发生的。

  它的用法如下:

 1      // DataGridView.RowsAdded事件使用
2 private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
3 {
4 // string str = "";
5 for (int i = e.RowIndex; i < e.RowIndex + e.RowCount; i++)
6 {
7 // str += dataGridView1.Rows[i].Cells[2].Value.ToString() + " ";
8 }
9 // MessageBox.Show(str);
10 }

  值得注意的是:该事件并不是向DataGridView中添加一行被执行一次,有可能第一次添加一项,第二次添加三项、或者一项、或者剩余的全部……

  而且并不是第一次添加过第二次就不会添加……

  总之就是没有规律……

  那么我们可以通过从e.RowIndex(当前添加的第一行的索引)到 e.RowIndex + e.RowCount (已经添加项数)的次数的循环,并且通过变化的e.RowIndex的值取得真正被添加的行进行操作。

  看看我们如何将Female和Male替换为对应中文的:

 1 private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
2 {
3 // 如果能通过对象拿到性别,可以采用如下做法显示对应中文
4
5        // 取消对列属性的绑定
6 Column4.DataPropertyName = null;
7
8 for (int i = e.RowIndex; i < e.RowIndex + e.RowCount; i++)
9 {  
10 // 通过行(或项)的绑定对象拿到性别
11 dataGridView1.Rows[i].Cells[Column4.Index].Value =  // 判断该如何显示,此处的DataBoungItem相当于Tag是在绑定数据源时自动绑定的(当然,它是只读的……)
12 (dataGridView1.Rows[i].DataBoundItem as SE).Sex == Gender.Female ? "女" : "男";
13 }
14 }

  善于利用控件的属性和事件会让我们的开发事半功倍!

  

  

WinForm编程数据视图之DataGridView浅析的更多相关文章

  1. 在VS2005编程中,有的时候DataGridView数据源有几个表的联合查询,而系统又有限制为一个表,怎么办?

    在VS2005编程中,有的时候DataGridView数据源有几个表的联合查询,而系统又有限制为一个表,怎么办? 解决方法:在SqlServer的企业管理器里增加一个视图吧!!!!!!!!(从来没用过 ...

  2. SharePoint 2013 Designer系列之数据视图筛选

    在SharePoint中,我们经常需要对列表进行简单的筛选,这时,数据视图就有作用了,我们可以定制对于字段的筛选,来进行展示:特别的,筛选不同于搜索,并没有对于附件或者文档的全文检索,如果需要全文检索 ...

  3. SharePoint 2013 Designer系列之数据视图

    在SharePoint使用中,数据展示是一块很重要的部分,很多时候我们会采用webpart的形式,但是有一些情况,我们不必使用开发,仅需使用Designer即可,下面让我简单介绍下数据视图的使用. 1 ...

  4. Atitit..组件化事件化的编程模型--(2)---------Web datagridview 服务器端控件的实现原理and总结

    Atitit..组件化事件化的编程模型--(2)---------Web datagridview 服务器端控件的实现原理and总结 1. 服务端table控件的几个流程周期 1 1.1. 确认要显示 ...

  5. ADO.NET事务处理,初始回调函数,多张表的数据在同一个DataGridView中展示

    执行ADO.NET事务包含四个步骤,接下来以Transaction对象为例介绍. (1)调用SQLConnection对象的BeginTransaction()方法,创建一个SQLTransactio ...

  6. DataGridView绑定数据库,取得的数据插入到DataGridView指定列(一)

    实现: 点击button1,从数据库中获得数据,指定数据库的某列数据插入到DataGridView指定列 一.双击button1进入事件代码 private void button1_Click(ob ...

  7. SharePoint开发 - Excel数据导入到SharePoint自定义列表(数据视图方式)

    博客地址 http://blog.csdn.net/foxdave 本篇讲解一个有些新颖的SharePoint实例应用,给甲方做过项目的都有过体会,数据太多了,客户有Excel,要求实现批量导入. 效 ...

  8. C# winform编程中多线程操作控件方法

    private void Form1_Load(object sender, EventArgs e) { Thread newthread = new Thread(new ThreadStart( ...

  9. C#使用oledb方式将excel数据导入到datagridview后数据被截断为 255 个字符

    问题描述:在使用oledb方式将excel数据导入到datagridview中,在datagridview单元格中的数据没有显示全,似乎只截取了数据源中的一段 解决方案:1.关于该问题,微软官方答案: ...

随机推荐

  1. AFNetworking使用方法

    官网下载2.5版本:http://afnetworking.com/ 此文章是基于AFNetworking2.5版本的,需要看AFNetworking2.0版本的请看上一篇文章:AFNetworkin ...

  2. 我的android学习经历12

    自动匹配输入的内容(文章最后有一个问题有兴趣的可以解答一下,谢谢大神了) 这个主要是两个控件MultiAutoCompleteTextView和AutoCompleteTextView 这两个控件和T ...

  3. IOS的UI基础01

    内容大纲:(红色表示博主个人重点记忆) 1.指定启动界面 带箭头就是首次启动的页面2.两个常用的快捷键3.拖线子控件注意事项4.一般情况下,UIView的容器是控制器的View.5.didRecive ...

  4. javascript中的 类初始化,遍历for in 以及with的用法

    <script type="text/javascript"> function member(name,gender){ this.name=name; this.g ...

  5. android textview 设置text 字体

    1.使用不同的字库 mLocalClock.setTypeface(Typeface.SANS_SERIF); Typeface face = Typeface.createFromAsset(get ...

  6. CentOS6.5安装mysql5.1.73

    思路: 1.查看有无安装过mysql rpm -qa|grep mysql

  7. 关于EditText的一点深入的了解

    最近在开发android下的记事本程序时,频繁的使用EditText控件,折腾来折腾去,算是对其的了解更深入了一些.特将这些收获记录如下: 一.几个属性的介绍 android:gravity=&quo ...

  8. Json常用的转换

    简单记录一下jquery里面的JSON.parse()和JSON.stringify()函数,和js中的eval()函数的用法 1,JSON.parse 函数(常用) 作用:将 JavaScript ...

  9. C标准头文件概述

    C的C89标准一共定义了15个头文件,这些头文件具有幂等性(多次包含同一个头文件的效果等同于只包含了一个头文件,例外),独立性(每个标准头文件的正常工作都不需要以包含其他标准头文件为前提,也没有任何标 ...

  10. dba诊断之lock

    --产生锁的详细信息 select a.session_id, c.SERIAL#,d.spid, os_user_name, b.object_name,locked_mode,    c.sql_ ...