C#中的表格控件只有一个,那就是datagridview,不像QT中可以用QTableview,QTableWidget。新手拿到datagridview的第一个问题就是数据从哪里来?难道从设计器中一个个手动输入,到时候要变怎办?所以,我们这里说说DataGridView的手动操作。
 
一、手动操作DataGridView 这里我们是没有数据源的纯view控件的操作,后面第二部分我们再讲有数据源的操作。 
1、初步尝试 下面的代码声明并初始化完成列DataGridViewColumn、行DataGridViewRow 、单元格DataGridViewCell 对象。DataGridView必须先有列后有行,最后才是单元格cell ,初始化完成后你就可以直接将他们加入DataGridView的实例中了,如下代码dataGridView1就是在设计器的工具箱中直接拖放到窗体中的DataGridView控件。
1 2 3 4 5 6 7 8 DataGridViewColumn col = new  DataGridViewColumn(); DataGridViewRow row = new  DataGridViewRow(); DataGridViewCell cell = new  DataGridViewTextBoxCell(); cell.Value = "item" ; col.CellTemplate = cell;  col.HeaderText = "column01" ; dataGridView1.Columns.Add(col); 
效果: 
虽然,只有一行一列一个单元格,但如果我们搞懂了原理,那后面批量加入我们需要的行列和单元格就容易了。
 
这里了重点强调一下,加入的顺序应该是: 
1、初始化列
注意,一个列必须设定它自己这一列的单元格格式母板,否则就会报错。如: 
1 2 3 cell= new  DataGridViewTextBoxCell();  col.CellTemplate = cell; 
2、批量加入 批量加入无非就是加入了一些循环,过程和单个单元格的加入几乎没有差别。每次加入的行或者列或者单元格都必须是一个新对象,也就是要new一个新的对象 ,否则就不能成功加入。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 DataGridViewColumn col; DataGridViewRow row; DataGridViewCell cell= new  DataGridViewTextBoxCell();          for  (int  i = 0 ; i < 6 ; i++){     col = new  DataGridViewColumn();     col.HeaderText = "col"  + i.ToString();            col.CellTemplate = cell;     dataGridView1.Columns.Add(col);     }             for  (int  i = 0 ; i <20 ; i++) {      row = new  DataGridViewRow();       for  (int  j = 0 ; j < 6 ; j++)      {         cell = new  DataGridViewTextBoxCell();         cell.Value = "item"  + i.ToString() + j.ToString();         row.Cells.Add(cell);      }      dataGridView1.Rows.Add(row);      } 
运行的效果如下: 
这里,我们将加入行和加入单元格同时进行的,你也可以加入行和加入列完成后,单独对单元格进行赋值
 
代码如下: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 for  (int  i = 0 ; i < 20 ; i++) {      row = new  DataGridViewRow();                                          dataGridView1.Rows.Add(row);  }  for  (int  i = 0 ; i < 6 ; i++)      for  (int  j = 0 ; j < 20 ; j++)          dataGridView1.Rows[j].Cells[i].Value = "item"  + j.ToString() + i.ToString(); 
3、带数据的行的加入rows.Add 行的加入我们利用add方法来完成,它有三个重载,所以我们可以用多种方式加入,前面我们就已经使用过了它的最常见的重载,直接在add的参数中加入row
1 2 dataGridView1.Rows.Add(row); 
这里我们使用数组加入也很方便: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16  string [] row0 = { "Jack" , "1880" , "2022-12-5" ,"12.5" ,"true"  };  string [] row1 = { "Smith" , "2208" , "2022-02-15" , "538" , "true"  };  dataGridView1.Rows.Add(row0);  dataGridView1.Rows.Add(row1);  dataGridView1.Rows.Add(new  string [] { "Tome" , "1208" , "2012-2-15" , "1.2" , "true"  });    List<string > values = new  List<string >();  values.Add("Jone" );  values.Add("1222" );        values.Add("2022-05-12" );  values.Add("23.2" );  values.Add("false" );  dataGridView1.Rows.Add(values.ToArray()); 
运行效果: 
还有一个重载是add(int ),这个专门从来加入空行,比如加入1000个空行,那就直接在参数中输入1000:
 
1 2 dataGridView1.Rows.Add(1000 ); 
二、数据来源DataSource 数据来源可以是自己从数据库中获取,也可以自己构建一个DataTable,也可以读入字符流或者字符列表等。这里分别演示。DataSource它的特点是:任何实现IListSource接口的类都可以作为它的右值。 
1、来自列表List 我们将列表中装入一个对象,当然,这个对象有多少特征,我们就可以显示在表格中显示多少列
1 2 3 4 5 6 7 List<Student> students = new  List<Student>() {      new  Student() {Name="John" , Gender=true , Birthday=new  DateTime(2012 , 12 , 4 ),Age= 20 , Hight=15 },      new  Student() {Name="Jack" ,  Gender=true , Birthday=new  DateTime(2022 , 10 , 12 ), Age=10 , Hight=125 }  };  dataGridView1.DataSource = students.Select(x => new  { x.Name, x.Gender, x.Birthday, x.Age, x.Hight }).ToList(); 
运行效果: 
2、来自自定义DataTable 既然是我们手动自定义的一个表,那么我们就必须给它定义行列和单元格内容。这的Datatable只是提供数据,与视图View无关,那么它的责任就是组织好数据给视图来显示,这在MVC中就属于model层。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17     DataTable dt = new  DataTable();     dt.Columns.Add("col1" , typeof (System.String));     dt.Columns.Add("col2" , typeof (System.String));     dt.Columns.Add("col3" , typeof (System.String));     dt.Columns.Add("col4" , typeof (System.String));     dt.Columns.Add("col5" , typeof (System.String));     dt.Columns.Add("col6" , typeof (System.String));     for (int  i = 0 ; i < 10 ; i++)     {         dt.Rows.Add(dt.NewRow());         for (int  j = 0 ; j < 6 ; j++)             dt.Rows[i][j]="item"  + j.ToString() + i.ToString();     } dataGridView1.DataSource =dt; 
我们上面所有的行,我们使用的格式都是String的,便于统一用循环添加,我们我们想要添加其他的格式的数据可以这样添加:
1 2 3 4 5 6 7 8 9 DataTable dt = new  DataTable(); dt.Columns.Add("col1" , typeof (System.Int32)); dt.Columns.Add("col2" , typeof (System.String)); dt.Columns.Add("col3" , typeof (System.DateTime)); dt.Columns.Add("col4" , typeof (System.Boolean)); dt.Columns.Add("col5" , typeof (System.Int16)); dt.Columns.Add("col6" , typeof (System.Decimal)); 
关于赋值,使用二维数组 的方式直接给单元格赋值即可:
1 2 dt.Rows[i][j]="item"  + j.ToString() + i.ToString(); 
最后,我们给DataGridView实例指定数据源DataSource 属性即可,这里我们指定为我们刚刚手动建立的DataTable。
 
运行效果: 
看起来,和前面我们直接对DataGridView手动操作得到的表格没有什么两样,但实际我们此时已经使用了MVC 的概念了,一个负责的是视图一个负责的是数据 。
3、动态建立表格 
我们首先定义两个List分别存放表格的字段类型和值 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 List<string > typeDef = new  List<string >(); typeDef.Add("System.Int32" ); typeDef.Add("System.String" ); typeDef.Add("System.DateTime" ); typeDef.Add("System.Decimal" ); typeDef.Add("System.Boolean" ); List<string > values = new  List<string >(); values.Add("1222" ); values.Add("Jone" ); values.Add("2022-05-12" ); values.Add("23.2" ); values.Add("false" ); dataGridView1.DataSource = initialDataTable(typeDef,values); 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 DataTable initialDataTable (List<String> strlist, List<String> vluelist )           DataTable dt = new  DataTable();           DataColumn col = new  DataColumn();           for  (int  i = 0 ; i < strlist.Count; i++)           {               col = new  DataColumn();               col.DataType = System.Type.GetType(strlist[i]);               dt.Columns.Add(col);           }           for  (int  i = 0 ; i < 10 ; i++)           {               dt.Rows.Add(dt.NewRow());               for  (int  j = 0 ; j < strlist.Count; j++)                   dt.Rows[i][j] = vluelist[j];           }           return  dt;       }   } 
运行效果: 
4、类和BindingList 类的特征属性直接显示在表格里可以通过BindingList来实现
1 2 3 4 5 6 BindingList<Student> list2 = new  BindingList<Student>(); list2.Add(new  Student("John" , true , new  DateTime(2012 , 12 , 4 ), 20 , 15 )); list2.Add(new  Student("Jack" , true , new  DateTime(2022 , 10 , 12 ), 10 , 125 )); list2.Add(new  Student("Tomy" , true , new  DateTime(1992 , 3 , 5 ), 30 , 5 )); dataGridView1.DataSource= list2; 
运行效果: 
5、来自文件字符流 
有了上面的基础后,我们就可以建立一个导入文本文件的表格,并且可以自动识别文本文件中的字段类型。
 
我们首先来看看效果: 
导入文本表格要做好文本字段之间的分割Split,这里不详说了,首先要从读入的文本流中取出表格的各列的名称和类型,然后再取出内容,然后分别形成数组
关键代码: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 StreamReader sr = new  StreamReader(filepath, Encoding.UTF8);         typetext = sr.ReadLine();         headtext = sr.ReadLine();         string [] typer = typetext.Split(',' );         ArrayList content = new  ArrayList();                  while  ((str=sr.ReadLine()) != null )         {             content.Add(str);             Console.WriteLine(str);          }                  List<string > typeDef = new  List<string >();         for  (int  i = 0 ; i < typer.Length; i++)         {             typeDef.Add("System."  + typer[i].ToString());          }                  ArrayList head = new  ArrayList();         string [] header = headtext.Split(',' );         for  (int  i = 0 ; i < header.Length; i++)         {             head.Add( header[i].ToString());         } 
将上述代码得到的三个列表传入下面的DataTable处理函数中即可得到DataGridView的DataSource需要的DataTable
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 DataTable initialDataTable (List<String> typelist, ArrayList headerlist,ArrayList contentarry )      DataTable dt = new  DataTable();      DataColumn col = new  DataColumn();      for  (int  i = 0 ; i < headerlist.Count; i++)      {          col = new  DataColumn();          col.ColumnName = headerlist[i].ToString();          col.DataType = System.Type.GetType(typelist[i]);          dt.Columns.Add(col);      }            for  (int  i = 0 ; i < contentarry.Count; i++)      {          dt.Rows.Add(contentarry[i].ToString().Split(',' ));                     }      return  dt;  } 
可以参考的文本: 
1 2 3 4 5 6 7 8 String,Boolean,Int32,DateTime,Int32,Int32 Name,Gender,ID,Birthday,Score1,Score2 John, true ,1908 , 2012 -12 -4 , 20 , 16  Jack, false2015, 2022 -10 -12 , 10 , 125  Tomy, true , 2047 ,1992 -3 -5 , 30 , 15 , Mophy, true , 1147 ,2014 -6 -3 , 40 , 24  Tollor, false ,2347 ,2102 -2 -15 , 50 , 55  
6、来自数据库 如果有数据库,那是最好不过的啦,直接将查询所得的表赋值给DataGridView的DataSource即可。
有了sqlite的环境,我们可以开始组织数据库读取了。这里我们调用的句子非常少,其实这是直接通过SQLiteDataAdapter 填充了一个新建的DataTable而已。
1 2 3 4 5 6 7 8 9 string  constr = "Data Source=tbdb.db;" ;  string  sql = "select * from TestTab" ;SQLiteDataAdapter mAdapter = new  SQLiteDataAdapter(sql, constr); DataTable dt = new  DataTable(); mAdapter.Fill(dt); dataGridView1.DataSource = dt;            
数据库中的表: 
运行效果: 
7、用到的student类 上面用到的student类,这里列出来省得大家重新编写: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class  Student {     string  _name = "" ;     bool  _gender =false ;     DateTime _birthday;     int  _age;     decimal  _hight;     public  string  School;     public  Student (         School = "" ;     }     public   Student (string  name, bool  gender, DateTime birthday, int  age, decimal  hight         Name = name;         Gender = gender;         Birthday = birthday;         Age = age;         Hight = hight;         School = "" ;          }     public  string  Name{get  { return  _name; }set  { _name = value ; }}     public  bool  Gender{get  { return  _gender; } set  { _gender = value ; }}     public  DateTime Birthday{ get  { return  _birthday; } set  { _birthday = value ; } }     public  int  Age { get  { return  _age; } set  { _age = value ; } }     public  decimal  Hight { get  { return  _hight; } set  { _hight = value ; } }     public  List<int > Scores { get ; set ; } } 
最后 其实关于DataGridView的操作还有很多,控件中最复杂的就属它了,所以如果说你要重新编写一个自定义控件,它也是最复杂的,这里我们只是讲了表格的数据填充,后面一篇我们会讲到样式设置和编辑,有时间我们还可以讲讲自定义DataGridView的编写。感兴趣的童鞋可以继续关注。
其他补充 datagridview默认选中第一行 设置datagridview在加载时默认选中第一行:
1 2 this .dataGridView1.Rows[0 ].Selected = true ;
例如: 
1 2 3 4 5 6 7 8 9 private  void  deplane_Load (object  sender, EventArgs e                                  this .onLine_InfoTableAdapter.Fill(this .charge_sysDataSet.OnLine_Info);            dataGridView1.AllowUserToAddRows = false ;            dataGridView1.Rows[0 ].Selected = true ;        }在这里插入代码片 
C# 向datagridview添加一行,并使他位于第一行 1 datagridview.Rows.Insert(0 , row); 
点击DataGridView时获取当前单元格信息(这个也很有用!) 
在使用DataGridView控件时, 表中信息有时需要提取,因此,需使用获取坐标的方法,和获取内容的方法。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 using  System;using  System.Collections.Generic;using  System.ComponentModel;using  System.Data;using  System.Drawing;using  System.Linq;using  System.Text;using  System.Windows.Forms;  namespace  Test_DataGridView {     public  partial  class  Form1  : Form      {         public  Form1 (             InitializeComponent();         }           private  void  Form1_Load (object  sender, EventArgs e             dataGridView1.DataSource = Source();         }                    private  DataTable Source (             DataTable mydt = new  DataTable();             mydt.Columns.Add("姓名" );             mydt.Columns.Add("年龄" );             mydt.Columns.Add("分数" );             String[,] str = new  String[,] { { "张三" , "21" , "90"  }, { "李四" , "22" , "93"  }, { "王五" , "23" , "99"  } };               for  (int  i = 0 ; i < 3 ; i++)             {                 DataRow dr = mydt.NewRow();                 dr[0 ] = str[i, 0 ];                 dr[1 ] = str[i, 1 ];                 dr[2 ] = str[i, 2 ];                 mydt.Rows.Add(dr);             }             return  mydt;           }                    private  void  dataGridView1_CellClick (object  sender, DataGridViewCellEventArgs e                          int  col = dataGridView1.CurrentCellAddress.X + 1 ;             int  row = dataGridView1.CurrentCellAddress.Y + 1 ;                                      String content = dataGridView1.CurrentCell.Value.ToString();               MessageBox.Show("行:"  + row.ToString() + "   列:"  + col.ToString()+"      内容:" +content);           }                } } 
在C#中将datagridview中的数据与图表绑定 我正在创建一个应用程序,它用于确定原始数据,并将这些原始数据值导入到datagridview中。
通过DataGridview对图表使用以下代码(未验证过,不知是否行) 
1 2 3 4 5 6 7 8 9 10 foreach  (DataGridViewRow row in  datagridview.Rows)            {                                  Series S = chartBpComplaince.Series.Add(row.Cells[2 ].Value.ToString());                  S.Points.AddXY(row.Cells[4 ].Value.ToString(), row.Cells[3 ].Value.ToString());                  S.ChartType = SeriesChartType.Column;                  S.IsValueShownAsLabel = true ; } 
相关链接(侵删) 
C#手动操作DataGridView之——使用各种数据源填充表格实例 datagridview默认选中第一行方法 【C#语言】DataGridView获取当前单元格信息 如何在C#中将datagridview中的数据与图表绑定?  
=================我是分割线================= 欢迎到公众号来唠嗑: