c#学习笔记-----Listview 、dataGridView 控件

1 概述

  listView和dataGridView是c#显示控件中比较复杂的控件,(还有一个treeView也比较复杂,但是在此没有太大的关联性)当需要显示大量的数据时候,一些box控件已经不能满足需要了。在大量数据显示时,至于什么时候使用listView(一般数据保存在内存中),什么时候使用使用dataGridView(一般数据保存在数据库中)就要看需求了。其实listView和dataGridView有很多相同的地方,可以说掌握了其中一个,另一个也就差不多了。正如开头所说这2个控件使用起来并不简单,主要的难点是过于庞杂的属性和方法列表,过于繁杂的事件,让初学者晕头转向不知道该从何处下手,所以一个好的学习路线是非常必要的。鉴于控件的复杂性本篇笔记借鉴peterzb的路线,部分代码也有所借鉴,此处附上原文链接:http://www.cnblogs.com/peterzb/archive/2009/05/29/1491891.html。想要深入研究,可以去看原文。

  fhbds!

 2 ListView

  先看一下我实现的效果吧!

  

  2.1 listView视图

   listView视图一共有5种视图,包括Details、LargeIcon、List、SmallIcon、Tile(默认为 LargeIcon),因为默认是LargeIcon视图,所以一般刚开始的新手很难做到上面这种列表的显示方式。此处也只介绍Details(上面实现的方式),其它视图不太适合显示数据,倒是适合显示图片,此时并不感兴趣!接下来讲一下我实现的路线,如果自己没有路线的可以跟着一起做,只附上主要代码,需要全部的请留下QQ邮箱!

  为了避免listView在更新数据的时候有闪烁现象,不使用System.Windows.Forms.ListView  而是自定义一个子类去继承它。

 1  class ListViewNF : System.Windows.Forms.ListView  
 2     {
 3         public ListViewNF()//避免闪烁
 4         {
 5              
 6             this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
 7 
 8         
 9             this.SetStyle(ControlStyles.EnableNotifyMessage, true);
10         }
11 
12         protected override void OnNotifyMessage(Message m)
13         {
14            
15             if (m.Msg != 0x14)
16             {
17                 base.OnNotifyMessage(m);
18             }
19         }  
20     }

  接下来创建一个listView1,此时需要到Form1.designer.cs做以下修改: this.listView1 = new show.ListViewNF();

                                                                          private ListViewNF listView1; 

  原本这两句是this.listView1=new System.Windows.Forms.ListView1();建好之后,可以按照上面把页面的一些button和textBox建好,接下来就一一实现即可。

首先需要实现窗体加载事件,一开始就把listView的一些属性确立下来,各属性已在注释中说明。

 1  private void Form1_Load(object sender, EventArgs e)
 2         {
 3             listView1.View = View.Details;//设置视图   获取或设置项在控件中的显示方式
 4             listView1.FullRowSelect = true;//设置是否行选择模式
 5             listView1.GridLines = true;//设置网格线
 6             listView1.AllowColumnReorder = true;//设置是否可拖动列标头来对改变列的顺序。
 7             listView1.MultiSelect = true;//设置是否可以选择多个项
 8             listView1.LabelEdit = true;//设置用户是否可以编辑控件中项的标签,对于Detail视图,只能编辑行第一列的内容
 9             listView1.CheckBoxes = true;//设置控件中各项的旁边是否显示复选框
10 
11 
12             listView1.SmallImageList = imageList1;//设置图标  
13 
14             //添加列  
15             listView1.Columns.Add("序号", 100, HorizontalAlignment.Left);
16             listView1.Columns.Add("商品名称", 150, HorizontalAlignment.Left);
17             listView1.Columns.Add("商品数量", 150, HorizontalAlignment.Left);
18             listView1.Columns.Add("商品单价", 80, HorizontalAlignment.Left);
19             listView1.Columns.Add("商品产地", 80, HorizontalAlignment.Left);
20 
29 
30             listView1.BeginUpdate();
33             listView1.EndUpdate();  
34         }

  Details视图可以在第一列显示图标,想要加入图标的可以创建一个imageList控件,加入图片方式如下:

  listView通过index和图片绑定,需要预先设置几个全局变量,后面要用到连接数据库,所以一并全部加上。

1         public int count = 0;
2         public int pictureCount = 0;
3        
4         public static string dataSource = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=2013-20130829TH)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=oracle)));";
5         public static string persistSecurityInfo = "Persist Security Info=True;";
6         public static string userID = "User ID=SYSTEM;";
7         public static string password = "Password=admin;";
8         public static string connectionString = dataSource + persistSecurityInfo + userID + password;

  实现添加记录:

 1  private void button1_Click(object sender, EventArgs e)
 2         {
 3                 // ListViewItem Item = new ListViewItem();  
 4                 //Item.SubItems.Clear();
 5 
 6                 //添加行  
 7                 var item = new ListViewItem();
 8                 item.SubItems.Clear();
 9                 if (pictureCount>=imageList1.Images.Count-1) {
10                     pictureCount = 0;
11                 }
12                 pictureCount++;
13                 item.ImageIndex = pictureCount;
14                 count++;
15                 item.Text = count.ToString(); //序号
16 
17                 if (count % 3 == 0)
18                 {
19                     item.SubItems.Add("西瓜"); //商品名称    
20                     item.SubItems.Add("23"); //商品数量  
21                     item.SubItems.Add("1129"); //商品单价  
22                     item.SubItems.Add("巴西"); //商品产地  
23                 }
24                 else if (count % 3 == 1)
25                 {
26                     item.SubItems.Add("苹果"); //商品名称    
27                     item.SubItems.Add("56"); //商品数量  
28                     item.SubItems.Add("9"); //商品单价  
29                     item.SubItems.Add("美国");
30                 }
31                 else {
32                     item.SubItems.Add("玉米"); //商品名称    
33                     item.SubItems.Add("6"); //商品数量  
34                     item.SubItems.Add("9999"); //商品单价  
35                     item.SubItems.Add("中国");
36                 }
37 
38 
39 
40                 listView1.BeginUpdate();
41                 listView1.Items.Add(item);
42                 listView1.Items[listView1.Items.Count - 1].EnsureVisible();//滚动到最后  
43                 listView1.EndUpdate();
44                 item.EnsureVisible(); //关键的实现函数
45         }

   清空:

1   private void button2_Click(object sender, EventArgs e)
2         {
3           //  this.listView1.Clear();  //从控件中移除所有项和列(包括列表头)。 
4             count = 0;
5             this.listView1.Items.Clear();  //只移除所有的项。
6         }

定位到第n行:

 1  private void button3_Click(object sender, EventArgs e)
 2         {
 3             int i = 1;
 4             if(textBox1.Text.Trim()==string.Empty ){
 5                 i = 1;
 6             }
 7            try{
 8               i= Convert.ToInt32(textBox1.Text.Trim());
 9            }catch(Exception ex){
10                i = 1;
11                MessageBox.Show(ex.Message);
12            }
13 
14             if(i<=0 || i>=count){
15                 i = count;
16             }
17 
18              listView1.EnsureVisible(i - 1);
19         }

查找:

 1  private void button4_Click(object sender, EventArgs e)
 2         {
 3             ListViewItem foundItem = this.listView1.FindItemWithText(this.textBox2.Text.Trim(), true, 0);    //参数1:要查找的文本;参数2:是否子项也要查找;参数3:开始查找位置 
 4 
 5             if (foundItem != null)
 6             {
 7 
 8                 this.listView1.TopItem = foundItem;  //定位到该项 
 9 
10                //foundItem.ForeColor = Color.Red;
11                 foundItem.BackColor = Color.Lime;//背景色
12             } 
13         }

选中移除:

1  private void button7_Click(object sender, EventArgs e)
2         {
3            
4             foreach (ListViewItem lvi in listView1.SelectedItems)  //选中项遍历 
5             {
6                 //listView1.Items.RemoveAt(lvi.Index); // 按索引移除 
7                 listView1.Items.Remove(lvi);   //按项移除 
8             } 
9         }

获取勾选中的:

 1  private void button6_Click(object sender, EventArgs e)
 2         {
 3             int k = 0;
 4             int m = listView1.CheckedItems.Count;
 5             string[] a = new string[m];
 6             Queue<string> Q = new Queue<string>();
 7 
 8             for (int i = 0; i < m; i++)
 9             {
10                 if (listView1.CheckedItems[i].Checked)
11                 {
12                     Q.Enqueue(listView1.CheckedItems[i].SubItems[1].Text);//获取勾选的第二个栏位
13                 }
14             }
15             while (Q.Count > 0)
16             {
17                 a[k] = Q.Dequeue();
18                 k++;
19             }
20 
21             foreach (var i in a)
22             {
23                 textBox3.Text += i.ToString();
24             }
25         }

获取点击选中的:

 1         private void button8_Click(object sender, EventArgs e)
 2         {
 3             ListView.SelectedListViewItemCollection svc =this.listView1.SelectedItems;
 4 
 5          
 6             foreach (ListViewItem item in svc)
 7             {
 8                 textBox3.Text = item.SubItems[1].Text;//获取选中的第二个栏位
 9 
10             }
11         }

实现点击表头可以排序,首先需要自己构造一个排序器,其次要实现一个点击表头事件:

 1  class ListViewSort : IComparer
 2     {
 3         private readonly int _col;
 4         private readonly bool _descK;
 5 
 6         public ListViewSort()
 7         {
 8             _col = 0;
 9         }
10 
11         public ListViewSort(int column, object desc)
12         {
13             _descK = (bool)desc;
14             _col = column; //当前列,0,1,2...,参数由ListView控件的ColumnClick事件传递    
15         }
16 
17         public int Compare(object x, object y)
18         {
19             int tempInt = String.CompareOrdinal(((ListViewItem)x).SubItems[_col].Text,((ListViewItem)y).SubItems[_col].Text);
20             if (_descK)
21             {
22                 return -tempInt;
23             }
24             return tempInt;
25         }  
26 
27     }
 1         private void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
 2         {
 3             if (listView1.Columns[e.Column].Tag == null)
 4             {
 5                 listView1.Columns[e.Column].Tag = true;
 6             }
 7             var tabK = (bool)listView1.Columns[e.Column].Tag;
 8             listView1.Columns[e.Column].Tag = !tabK;
 9             listView1.ListViewItemSorter = new ListViewSort(e.Column, listView1.Columns[e.Column].Tag);
10             //指定排序器并传送列索引与升序降序关键字    
11             listView1.Sort();//对列表进行自定义排序 
12         }

从数据库获取数据需要有一些执行sql的方法,可以参考我另外一篇笔记,此处的方法直接拿来用:

 1   public static OracleDataReader ExecuteReader(string connectionString, string strsql)
 2         {
 3             OracleConnection conn = new OracleConnection(connectionString);
 4             conn.Open();
 5             OracleCommand cmd = new OracleCommand(strsql, conn);
 6             try
 7             {
 8                 //CommandBehavior是一个枚举类型
 9                 OracleDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
10 
11                 return rdr;
12             }
13             catch
14             {
15                 conn.Close();
16                 throw;
17             }
18         }
19 
20 
21        private void button5_Click(object sender, EventArgs e)
22         {
23             if (pictureCount >= imageList1.Images.Count - 1)
24             {
25                 pictureCount = 0;
26             }
27 
28             try
29             {
30                 string sql1 = @"select * from goods";
31                 OracleDataReader odr = ExecuteReader(connectionString, sql1);
32                 while(odr.Read()){
33                     var lvi = new ListViewItem(odr[0].ToString());
34 
35                     if (pictureCount >= imageList1.Images.Count - 1)
36                     {
37                         pictureCount = 0;
38                     }
39                     lvi.ImageIndex = pictureCount;
40                     pictureCount++;
41 
42                     lvi.SubItems.Add(odr[1].ToString());
43                     lvi.SubItems.Add(odr[2].ToString());
44                     lvi.SubItems.Add(odr[3].ToString());
45                     lvi.SubItems.Add(odr[4].ToString());
46 
47                     listView1.BeginUpdate();
48                     this.listView1.Items.Add(lvi);
49                     listView1.Items[listView1.Items.Count - 1].EnsureVisible();//滚动到最后  
50                     listView1.EndUpdate();
51                     lvi.EnsureVisible(); //关键的实现函数
52                 }
53                 odr.Close();
54             }
55             catch (Exception ex)
56             {
57                MessageBox.Show(ex.Message);
58             }
59         }

效果如下:

3 dataGridView
  dataGridView主要介绍绑定2种数据源,一种是list,另一种是数据库。
  先看下效果吧!






  首先新建一个dataGridView和一个bindingSource1控件,再按照上图建立其他的控件。首先介绍一下从数据库获取数据.
首先还是先在窗体加载事件中设置加载dataGridView一些基本参数:
 1   private void Form1_Load(object sender, EventArgs e)
 2         {
 3             //string strSql = "select * from sima";
 4             //GetData(strSql);
 5             dataGridView1.AllowUserToAddRows = false;//禁止最后一行
 6             dataGridView1.GridColor = Color.Red;//网格线
 7             dataGridView1.MultiSelect = false;//禁止多行选择
 8             dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;// 单击选中整行,枚举
 9             //dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing; 
10             dataGridView1.AllowUserToResizeColumns = false; // 禁拖动列宽度
11             dataGridView1.AllowUserToResizeRows = false; // 禁拖动行高度
12             dataGridView1.AllowUserToOrderColumns = true;//拖动
13             dataGridView1.Font = new Font("微软雅黑", 13);   
14         }

为了让一个dataGridView能显示不同的表,先抽取出通过传入一个sql语句,绑定相应数据源的方法:

 1 private void GetData(string strSql)
 2         {
 3             try
 4             {
 5                 dataGridView1.DataSource = bindingSource1;
 6                 OracleConnection connection = new OracleConnection(connectionString);
 7                 connection.Open();
 8                 //string strSql = "select * from sima";
 9                 OracleDataAdapter dataAdapter = new OracleDataAdapter(strSql, connection);
10 
11                 DataTable table = new DataTable();
12                 table.Locale = System.Globalization.CultureInfo.InvariantCulture;
13                 dataAdapter.Fill(table);
14                 bindingSource1.DataSource = table;
15                // dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader);
16             }
17             catch (Exception  ex)
18             {
19                 MessageBox.Show(ex.Message);
20             }
21         }

自动绘制行号的事件:

 1   private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
 2         {
 3             if (e.ColumnIndex < 0 && e.RowIndex >= 0) // 绘制 自动序号
 4             {
 5                 e.Paint(e.ClipBounds, DataGridViewPaintParts.All);
 6                 Rectangle vRect = e.CellBounds;
 7                 vRect.Inflate(-2, 2);
 8                 TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(), e.CellStyle.Font, vRect, e.CellStyle.ForeColor, TextFormatFlags.Right | TextFormatFlags.VerticalCenter);
 9                 e.Handled = true;
10             }
11 
12             if (e.RowIndex % 2 == 0)
13             { // 行序号为双数(含0)时 
14                 e.CellStyle.BackColor = Color.White;
15             }
16             else
17             {
18                 e.CellStyle.BackColor = Color.Honeydew;
19             }
20             e.CellStyle.SelectionBackColor = Color.Gray; // 选中单元格时,背景色
21             e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; //单位格内数据对齐方式
22         }

司马老贼:

 1  private void button1_Click(object sender, EventArgs e)
 2         {
 3             string strSql = "select * from sima";
 4             GetData(strSql);
 5             dataGridView1.Columns[0].HeaderCell.Value = "序号";
 6             dataGridView1.Columns[1].HeaderCell.Value = "姓名";
 7             dataGridView1.Columns[2].HeaderCell.Value = "年龄";
 8             dataGridView1.Columns[3].HeaderCell.Value = "官职";
 9             dataGridView1.Columns[4].HeaderCell.Value = "朝代";
10             dataGridView1.Columns[5].HeaderCell.Value = "攻击力";
11             dataGridView1.Columns[6].HeaderCell.Value = "智力";
12         }

商品:


 1     private void button2_Click(object sender, EventArgs e)
 2         {
 3             string strSql = "select * from goods";
 4             GetData(strSql);
 5             dataGridView1.Columns[0].HeaderCell.Value = "编号";
 6             dataGridView1.Columns[1].HeaderCell.Value = "商品名";
 7             dataGridView1.Columns[2].HeaderCell.Value = "数量";
 8             dataGridView1.Columns[3].HeaderCell.Value = "单价";
 9             dataGridView1.Columns[4].HeaderCell.Value = "产地";
10 
11         }

获取当前值:

1  private void button5_Click(object sender, EventArgs e)
2         {
3             textBox1.Text = dataGridView1.CurrentCell.Value.ToString();
4             textBox2.Text = dataGridView1.CurrentCell.ColumnIndex.ToString();
5             textBox3.Text = dataGridView1.CurrentCell.RowIndex.ToString();
6         }

定位:

1   private void button6_Click(object sender, EventArgs e)
2         {
3             dataGridView1.CurrentCell = dataGridView1[2, 2]; 
4         }

下遍历:

1  private void button7_Click(object sender, EventArgs e)
2         {
3             int row = this.dataGridView1.CurrentRow.Index + 1;
4             if (row > this.dataGridView1.RowCount - 1)
5                 row = 0;
6             this.dataGridView1.CurrentCell = this.dataGridView1[0, row]; 
7         }

上遍历:

1  private void button8_Click(object sender, EventArgs e)
2         {
3             int row = this.dataGridView1.CurrentRow.Index - 1;
4             if (row < 0)
5                 row = this.dataGridView1.RowCount - 1;
6             this.dataGridView1.CurrentCell = this.dataGridView1[0, row]; 
7         }

  实现绑定list有点麻烦,但是我们只要明确一点我们要的效果是:我们的操作是对源操作,源变了,显示跟着变!或者就是对显示操作,显示变了,源跟着变!除此之外的操作方式都是极其危险的!我个人更倾向于前者!

  先建一个全局的list和list中存储的实体类emplyee

 1 public static List<Emplyee> emp=new List<Emplyee>();

2 public BindingList<Emplyee> empbd = new BindingList<Emplyee>(emp); 

 1 public class Emplyee
 2     {
 3         private string empName;
 4         private string empAge;
 5         private string empSlary;
 6 
 7 
 8         public string ChangeEmpAge
 9         {
10             set
11             {
12                 empName = value;
13             }
14             get
15             {
16                 return empName;
17             }
18         }
19 
20         public string ChangeEmpName
21         {
22             set
23             {
24                 empAge = value;
25             }
26             get
27             {
28                 return empAge;
29             }
30         }
31 
32         public string ChangeEmpSlary
33         {
34             set
35             {
36                 empSlary = value;
37             }
38             get
39             {
40                 return empSlary;
41             }
42 
43         }
44     }

list下获取数据源的方法:

1     public void getDataFromList()
2         {
3             this.dataGridView1.DataSource = empbd;
4         }

更新数据源的方法:

1         public void updateListUi() {
2 
3             this.dataGridView1.DataSource = null;
4             getDataFromList();
5         
6         }

添加记录:

 private void button4_Click(object sender, EventArgs e)
        {
      
            dataGridView1.CellPainting += dataGridView1_CellPainting;
            Emplyee emplyee = new Emplyee();
            emplyee.ChangeEmpName="张三";
            emplyee.ChangeEmpAge = "20";
            emplyee.ChangeEmpSlary = "三万";
            emp.Add(emplyee);
            updateListUi();

            dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;//自动铺满
            //dataGridView1.Columns[0].Width = 100;
            //dataGridView1.Columns[1].Width = 100;
            //dataGridView1.Columns[2].Width = 350;
            dataGridView1.Columns[0].HeaderCell.Value = "姓名";
            dataGridView1.Columns[1].HeaderCell.Value = "年龄";
            dataGridView1.Columns[2].HeaderCell.Value = "工资";
            dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.RowCount - 1;//滚到最后

        }

4 dataGridView实现分页显示

  有时候数据量特别大,滚动条表示无能为力的时候,就可以考虑一下分页显示。效果如下:

   首先还是先建一个dataGridView 和一个bindingSource和一个bindingnavigator(此空间有最顶部的那个效果,但是自己还要再改一下)。

首先还是窗体加载事件:

 1   private void Form1_Load(object sender, EventArgs e)
 2        {
 3            OracleConnection connection = new OracleConnection(connectionString);
 4            DataSet ds = new DataSet();
 5            connection.Open();
 6            string strSql = "select * from sima";
 7            OracleDataAdapter command = new OracleDataAdapter(strSql, connection);
 8            command.Fill(ds, "ds");
 9            connection.Close();
10            dtInfo = ds.Tables[0];
11            InitDataSet();
12        }

全局变量:

 1        public  int pageSize = 0;     //每页显示行数
 2        public int nMax = 0;         //总记录数
 3        public  int pageCount = 0;    //页数=总记录数/每页显示行数
 4        public int pageCurrent = 0;   //当前页号
 5        public int nCurrent = 0;      //当前记录行
 6        public DataSet ds = new DataSet();
 7        public DataTable dtInfo = new DataTable();
 8 
 9        public static string dataSource = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=2013-20130829TH)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=oracle)));";
10        public static string persistSecurityInfo = "Persist Security Info=True;";
11        public static string userID = "User ID=SYSTEM;";
12        public static string password = "Password=admin;";
13        public static string connectionString = dataSource + persistSecurityInfo + userID + password;

分页方法:

 1  private void InitDataSet()
 2        {
 3            pageSize = 20;      //设置页面行数
 4            nMax = dtInfo.Rows.Count;
 5 
 6            pageCount = (nMax / pageSize);    //计算出总页数
 7 
 8            if ((nMax % pageSize) > 0) pageCount++;
 9 
10            pageCurrent = 1;    //当前页数从1开始
11            nCurrent = 0;       //当前记录数从0开始
12 
13            LoadData();
14        }
15 
16        private void LoadData()
17        {
18            int nStartPos = 0;   //当前页面开始记录行
19            int nEndPos = 0;     //当前页面结束记录行
20 
21            DataTable dtTemp = dtInfo.Clone();   //克隆DataTable结构框架
22 
23            if (pageCurrent == pageCount)
24                nEndPos = nMax;
25            else
26                nEndPos = pageSize * pageCurrent;
27 
28            nStartPos = nCurrent;
29 
30            lblPageCount.Text = pageCount.ToString();
31            txtCurrentPage.Text = Convert.ToString(pageCurrent);
32 
33            //从元数据源复制记录行
34            for (int i = nStartPos; i < nEndPos; i++)
35            {
36                dtTemp.ImportRow(dtInfo.Rows[i]);
37                nCurrent++;
38            }
39            bdsInfo.DataSource = dtTemp;
40            bdnInfo.BindingSource = bdsInfo;
41            dgvInfo.DataSource = bdsInfo;
42        }

更新数据源:

 1    public void updateUI() {
 2            OracleConnection connection = new OracleConnection(connectionString);
 3            DataSet ds = new DataSet();
 4            connection.Open();
 5            string strSql = "select * from sima";
 6            OracleDataAdapter command = new OracleDataAdapter(strSql, connection);
 7            command.Fill(ds, "ds");
 8            connection.Close();
 9            dtInfo = ds.Tables[0];
10            InitDataSet();
11        }

分页点击事件:

 1  private void bdnInfo_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
 2        {
 3 
 4            if (e.ClickedItem.Text == "关闭")
 5            {
 6                this.Close();
 7            }
 8            if (e.ClickedItem.Text == "上一页")
 9            {
10                pageCurrent--;
11                if (pageCurrent <= 0)
12                {
13                    MessageBox.Show("已经是第一页,请点击“下一页”查看!");
14                    return;
15                }
16                else
17                {
18                    nCurrent = pageSize * (pageCurrent - 1);
19                }
20 
21                LoadData();
22            }
23            if (e.ClickedItem.Text == "下一页")
24            {
25                pageCurrent++;
26                if (pageCurrent > pageCount)
27                {
28                    MessageBox.Show("已经是最后一页,请点击“上一页”查看!");
29                    return;
30                }
31                else
32                {
33                    nCurrent = pageSize * (pageCurrent - 1);
34                }
35                LoadData();
36            }
37        }

隔行显示和行号显示事件:

 1        private void dgvInfo_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
 2        {
 3            if (this.dgvInfo.Rows.Count != 0)
 4            {
 5                for (int i = 0; i < this.dgvInfo.Rows.Count; )
 6                {
 7                    this.dgvInfo.Rows[i].DefaultCellStyle.BackColor = System.Drawing.Color.Pink;
 8                    i += 2;
 9                }
10            } 
11 
12 
13        }
14 
15        private void dgvInfo_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
16        {
17            Color color = ((DataGridView)sender).RowHeadersDefaultCellStyle.ForeColor;
18            if (((DataGridView)sender).Rows[e.RowIndex].Selected)
19                color = ((DataGridView)sender).RowHeadersDefaultCellStyle.SelectionForeColor;
20            else
21                color = ((DataGridView)sender).RowHeadersDefaultCellStyle.ForeColor;
22 
23            using (SolidBrush b = new SolidBrush(color))
24            {
25                e.Graphics.DrawString((e.RowIndex + 1).ToString(), e.InheritedRowStyle.Font, b, e.RowBounds.Location.X + 10, e.RowBounds.Location.Y + 6);
26            }
27 
28        }

编辑检查事件:


 1   private void dgvInfo_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
 2        {
 3            DataGridView dgv = (DataGridView)sender;
 4            //是否可以进行编辑的条件检查
 5            if (dgv.Columns[e.ColumnIndex].Name == "Column1" &&
 6                !(bool)dgv["Column2", e.RowIndex].Value)
 7            {
 8                // 取消编辑
 9                e.Cancel = true;
10            }
11        }

获取当前单元格:

 1 private void button1_Click(object sender, EventArgs e)
 2        {
 3            // 取得当前单元格内容
 4            textBox1.Text = dgvInfo.CurrentCell.Value.ToString();
 5            // 取得当前单元格的列 Index
 6            textBox2.Text = (dgvInfo.CurrentCell.ColumnIndex+1).ToString();
 7            // 取得当前单元格的行 Index
 8            textBox3.Text = (dgvInfo.CurrentCell.RowIndex+1).ToString();
 9 
10        }

定位:


1   private void button2_Click(object sender, EventArgs e)
2        {
3            dgvInfo.CurrentCell = dgvInfo[1, 1];
4        }

向下遍历   向上遍历:

 1   private void button3_Click(object sender, EventArgs e)
 2        {
 3            int row = this.dgvInfo.CurrentRow.Index + 1;
 4            if (row > this.dgvInfo.RowCount - 1)
 5                row = 0;
 6            this.dgvInfo.CurrentCell = this.dgvInfo[0, row]; 
 7        }
 8 
 9        private void button4_Click(object sender, EventArgs e)
10        {
11            int row = this.dgvInfo.CurrentRow.Index - 1;
12            if (row < 0)
13             row = this.dgvInfo.RowCount - 1;
14            this.dgvInfo.CurrentCell = this.dgvInfo[0, row];  
15        }

只读:


private void button5_Click(object sender, EventArgs e)
       {
          // dgvInfo.ReadOnly = true;

           // 设置 DataGridView1 的第2列整列单元格为只读
           dgvInfo.Columns[1].ReadOnly = true;

           // 设置 DataGridView1 的第3行整行单元格为只读
           dgvInfo.Rows[2].ReadOnly = true;

           // 设置 DataGridView1 的[0,0]单元格为只读
           dgvInfo[0, 0].ReadOnly = true;

       }
禁止添加:
1    private void button6_Click(object sender, EventArgs e)
2        {
3            // 设置用户不能手动给 DataGridView1 添加新行
4            dgvInfo.AllowUserToAddRows = false;
5            // 禁止DataGridView1的行删除操作。
6            dgvInfo.AllowUserToDeleteRows = false;
7        }

删除提示事件:

 1    private void dgvInfo_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
 2        {
 3            // 删除前的用户确认。
 4            if (MessageBox.Show("确认要删除该行数据吗?", "删除确认",
 5                MessageBoxButtons.OKCancel,
 6                MessageBoxIcon.Question) != DialogResult.OK)
 7            {
 8                // 如果不是 OK,则取消。
 9                e.Cancel = true;
10            }
11        }

删除指定行:

1    private void button7_Click(object sender, EventArgs e)
2        {
3            //删除名为"Column1"的列
4            dgvInfo.Columns.Remove("序号");
5            //删除第二列 
6            dgvInfo.Columns.RemoveAt(1);
7          // 删除第一行 
8            dgvInfo.Rows.RemoveAt(0);
9        }

删除选定行:

 1    private void button8_Click(object sender, EventArgs e)
 2        {
 3            foreach (DataGridViewRow r in dgvInfo.SelectedRows)
 4            {
 5                if (!r.IsNewRow)
 6                {
 7                    dgvInfo.Rows.Remove(r);
 8                }
 9            }
10        }

自动调整:

1     private void button9_Click(object sender, EventArgs e)
2        {
3            // 设定包括Header和所有单元格的列宽自动调整
4            dgvInfo.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
5 
6            // 设定包括Header和所有单元格的行高自动调整
7            dgvInfo.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
8        }

删除和添加:

  之前有说过删除的操作一定是对源进行操作,然后再去更新页面,如果你反着操作不是不行,但是你需要实现绑定行添加和移除触发事件,反之会减少很多麻烦!

 1   private void button10_Click(object sender, EventArgs e)
 2        {
 3          
 4            string sql = @"delete sima where name ='曹操'";
 5            int count = ExecuteNonQuery(connectionString, sql);
 6            if(count==1){
 7                MessageBox.Show("删除成功!");
 8            }
 9            updateUI();
10        }
11 
12     private void button11_Click(object sender, EventArgs e)
13        {
14            string sql = @"Insert into SIMA(SNUMBER, NAME, AGE, RATE, PLACE, FIGHT, SFROM, SIQ) Values('0', '曹操', '48', '魏王', '东汉', '95', '邺城', '85')";
15            int count = ExecuteNonQuery(connectionString, sql);
16            if (count == 1)
17            {
18                MessageBox.Show("添加成功!");
19            }
20            updateUI();
21        }

5 datagridView中显示下拉列表

     datagridView中显示下拉列表的实现借鉴了peterzb的代码,我只是对他的实现逻辑进行了稍微整理,想要深入研究,请看原文。

      实现思路及效果如下:

  

  首先还是新建一个dataGridview.

窗体加载事件:

 1  private void Form1_Load(object sender, EventArgs e)
 2         {
 3             // 绑定性别下拉列表框
 4             BindSex();
 5 
 6             //绑定数据表
 7             BindData();
 8 
 9             // 设置下拉列表框不可见
10             cmb_Temp.Visible = false;
11 
12             // 添加下拉列表框事件
13             cmb_Temp.SelectedIndexChanged += new EventHandler(cmb_Temp_SelectedIndexChanged);
14 
15             // 将下拉列表框加入到DataGridView控件中
16             this.dgv_User.Controls.Add(cmb_Temp);
17         }

新建一个下拉列表控件:

      实现绑定转换的方法:

 1    private void BindSex()
 2         {
 3             DataTable dtSex = new DataTable();
 4             dtSex.Columns.Add("Value");
 5             dtSex.Columns.Add("Name");
 6             DataRow drSex;
 7             drSex = dtSex.NewRow();
 8             drSex[0] = "1";
 9             drSex[1] = "";
10             dtSex.Rows.Add(drSex);
11             drSex = dtSex.NewRow();
12             drSex[0] = "0";
13             drSex[1] = "";
14             dtSex.Rows.Add(drSex);
15             cmb_Temp.ValueMember = "Value";
16             cmb_Temp.DisplayMember = "Name";
17             cmb_Temp.DataSource = dtSex;
18             cmb_Temp.DropDownStyle = ComboBoxStyle.DropDownList;
19         }

绑定数据源:

 1  private void BindData()
 2         {
 3             DataTable dtData = new DataTable();
 4             dtData.Columns.Add("ID");
 5             dtData.Columns.Add("Name");
 6             dtData.Columns.Add("Sex");
 7             DataRow drData;
 8             drData = dtData.NewRow();
 9             drData[0] = 1;
10             drData[1] = "张三";
11             drData[2] = "1";
12             dtData.Rows.Add(drData);
13             drData = dtData.NewRow();
14             drData[0] = 2;
15             drData[1] = "李四";
16             drData[2] = "1";
17             dtData.Rows.Add(drData);
18             drData = dtData.NewRow();
19             drData[0] = 3;
20             drData[1] = "王五";
21             drData[2] = "1";
22             dtData.Rows.Add(drData);
23             drData = dtData.NewRow();
24             drData[0] = 4;
25             drData[1] = "小芳";
26             drData[2] = "0";
27             dtData.Rows.Add(drData);
28             drData = dtData.NewRow();
29             drData[0] = 5;
30             drData[1] = "小娟";
31             drData[2] = "0";
32             dtData.Rows.Add(drData);
33             drData = dtData.NewRow();
34             drData[0] = 6;
35             drData[1] = "赵六";
36             drData[2] = "1";
37             dtData.Rows.Add(drData);
38             this.dgv_User.DataSource = dtData;
39         }

用户鼠标移到下拉列表处的事件:

 1   private void dgv_User_CurrentCellChanged(object sender, EventArgs e)
 2         {
 3             try
 4             {
 5                 if (this.dgv_User.CurrentCell.ColumnIndex == 2)
 6                 {
 7                     Rectangle rect = dgv_User.GetCellDisplayRectangle(dgv_User.CurrentCell.ColumnIndex, dgv_User.CurrentCell.RowIndex, false);
 8                     string sexValue = dgv_User.CurrentCell.Value.ToString();
 9                     if (sexValue == "1")
10                     {
11                         cmb_Temp.Text = "";
12                     }
13                     else
14                     {
15                         cmb_Temp.Text = "";
16                     }
17                     cmb_Temp.Left = rect.Left;
18                     cmb_Temp.Top = rect.Top;
19                     cmb_Temp.Width = rect.Width;
20                     cmb_Temp.Height = rect.Height;
21                     cmb_Temp.Visible = true;
22                 }
23                 else
24                 {
25                     cmb_Temp.Visible = false;
26                 }
27             }
28             catch
29             {
30             }
31         }

选择下拉列表框时改变DataGridView单元格的内容触发的事件:

 1   private void cmb_Temp_SelectedIndexChanged(object sender, EventArgs e)
 2         {
 3             if (((ComboBox)sender).Text == "")
 4             {
 5                 dgv_User.CurrentCell.Value = "";
 6                 dgv_User.CurrentCell.Tag = "1";
 7             }
 8             else
 9             {
10                 dgv_User.CurrentCell.Value = "";
11                 dgv_User.CurrentCell.Tag = "0";
12             }
13         }

滚动DataGridView触发事件:

 1  // 滚动DataGridView时将下拉列表框设为不可见
 2         private void dgv_User_Scroll(object sender, ScrollEventArgs e)
 3         {
 4             this.cmb_Temp.Visible = false;
 5         }
 6 
 7         // 改变DataGridView列宽时将下拉列表框设为不可见
 8         private void dgv_User_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
 9         {
10             this.cmb_Temp.Visible = false;
11         }

绑定数据表后将性别列中的每一单元格的Value和Tag属性(Tag为值文本,Value为显示文本):

 1  private void dgv_User_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
 2         {
 3             for (int i = 0; i < this.dgv_User.Rows.Count; i++)
 4             {
 5                 if (dgv_User.Rows[i].Cells[2].Value != null && dgv_User.Rows[i].Cells[2].ColumnIndex == 2)
 6                 {
 7                     dgv_User.Rows[i].Cells[2].Tag = dgv_User.Rows[i].Cells[2].Value.ToString();
 8                     if (dgv_User.Rows[i].Cells[2].Value.ToString() == "1")
 9                     {
10                         dgv_User.Rows[i].Cells[2].Value = "";
11                     }
12                     else if (dgv_User.Rows[i].Cells[2].Value.ToString() == "0")
13                     {
14                         dgv_User.Rows[i].Cells[2].Value = "";
15                     }
16                 }
17             }
18         }

6.0   结束

  其实有关listView和dataGridView的风骚的操作还有很多,有兴趣的可以去拜读peterzb的博客,以上所有有关借鉴的内容可能不全部是引用于peterzb,但是也都是来自于其的引用,不再一一拉出来示众。

有些鸟儿的羽毛太过耀眼,注定不是关在笼中的那种!
原文地址:https://www.cnblogs.com/wuxinwuxin/p/8168975.html