WinForm——DataGridView总结

简介: WinForm——DataGridView总结

常用属性

CurrentCell属性

获取或设置当前处于活动状态的单元格。语法:public DataGridViewCell currentCell{get;set;}


默认值时第一列中的第一个单元格,如控件中没有单元格,则为空引用。


例:DataGridView1.CurrentCell=DataGridView1[0,0];


取消默认选中行的办法1、dataGridView1.CurrentCell=null;


dataGridView1.ClearSelection();

dataGridView1.Row[0].Selected=false;

SelectionMode属性

获取或设置一个值,该值如何选择DataGridView的单元格。是DataGridViewSelectionMode的枚举值之一。


CellSelect


可以选定一个或多个单元格。


ColumnHeaderSelect


可以通过单击列的标头单元格选定此列。 通过单击某个单元格可以单独选定此单元格。


FullColumnSelect


通过单击列的标头或该列所包含的单元格选定整个列。


FullRowSelect


通过单击行的标头或是该行所包含的单元格选定整个行。


RowHeaderSelect


通过单击行的标头单元格选定此行。 通过单击某个单元格可以单独选定此单元格。


设置DataGridView的属性SelectionMode为FullRowSelect


这样就使DataGridView不是选择一个字段,而是选择一整行了


AllowUserToAddRows属性

获取或设置一个值,该值指示是否向用户显示添加行的选项。


如果向用户显示“添加行”选项,为 true;去掉默认添加新行则为false


FirstDisplayedScrollingRowIndex属性

获取或设置某一行的索引,该行是显示在 System.Windows.Forms.DataGridView 上的第一行。


让DataGridView的选中行在可视范围之内的方法:


int rowIndex=DataGridView1.SelectedRows[0].Index;


DataGridView1. FirstDisplayedScrollingRowIndex=rowIndex;


CurrentCellAddress属性

获取或设置当前单元格的行和列。当前单元格时DataGridView所在的单元格,他可以通过DataGridView的CurrentCell属性取得。使用CurrentCellAddress来确定单元格所在行DataGridView.CurrentCellAdress.Y和列:DataGridView.CurrentCellAdress.X。


DefaultCellStyle属性

在未设置其他单元格样式属性的情况下,获取或设置应用于 DataGridView 中的单元格的默认单元格样式。对单独一行进行样式设置:


dataGrid.Row[2]. DefaultCellStyle.BackColor=Color.Green;


dataGrid.Row[2]. DefaultCellStyle.Font =new System.Drawing.Font(“宋体”,9,System.Drawing.FontStyle.strikeout);


RowHeadersVisible属性

获取或设置一个,该值指示表头是否可见。


AutoGenerateColumns属性

获取或设置一个值,该值指示在设置 System.Windows.Forms.DataGridView.DataSource 或 System.Windows.Forms.DataGridView.DataMember  属性时是否自动创建列。


 如果应自动创建列,为 true;否则为 false。 默认值为 true。


AllowUserToResizeColumns属性

获取或设置一个值,该值指示用户是否可以调整列的大小。


AllowUserToResizeRows属性

 获取或设置一个值,该值指示用户是否可以调整行的大小。


常用事件

CurrentCellDirtyStateChanged事件

当单元格的内容已更改,但更改尚未保存时,该单元格将标记为已修改。此事件通常会在以下情况下发生:当单元格已编辑,但是更改尚未提交到数据缓存中时,或者当编辑操作被取消时。


在CurrentCellDirtyStateChanged事件处理程序调用CommitEdit 方法以引发 CellValueChanged 事件 。可以解决DataGridView无法及时响应Combobox值改变。


private void dataGridView1_ColumnDefaultCellStyleChanged(object sender, DataGridViewColumnEventArgs e)


       {


           if (this.dataGridView1.IsCurrentCellDirty == true)


           {


               this.dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);


           }


       }


加上以上代码,即可实现,某单元格更改即触发CellValueChanged事件


CellClick事件

在单元格的任何部分被单击时发生。


例:


   private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)


   {


      string aa = dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString();


}


CellValueChanged事件

在用户指定的值提交时发生 DataGridView.CellValueChanged 事件,通常是在焦点离开单元格时发生。


但对于复选框单元格,你通常会希望立即处理更改。 若要在单击单元格时提交更改,必须处理 DataGridView.CurrentCellDirtyStateChanged 事件。 在处理程序中,如果当前单元格为复选框单元,则调用 DataGridView.CommitEdit 方法,并传入 Commit 值。


更改单元格的值时,不会自动对控件中的行进行排序。 若要在用户修改单元格时对控件进行排序,请在 CellValueChanged 事件处理程序中调用 Sort 方法。


使用举例

DataGridView取消默认选中行。

       DataGridView1.ClearSelection();


或者


dataGridView1.CurrentCell=null;


或者


dataGridView1.Row[0].Selected=false;


实现某一列只能输入数字

最近在开发一个项目时,要求某一列只能够输入数字,其它的字符都不接受,Microsoft 没有提供这个功能,


只能自己用代码实现,在网上找了一下,大多数都在输入完成后才验证的。这样不爽,我这个代码可以在输入进就屏蔽了非数字的字符。主要是在 EditingControlShowing事件中完成 。看代码:  


public  DataGridViewTextBoxEditingControl CellEdit = null; // 声明 一个 CellEdit  


 private void datagridyf_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)  


       {  


           CellEdit = (DataGridViewTextBoxEditingControl)e.Control; // 赋值  


           CellEdit.SelectAll();  


           CellEdit.KeyPress += Cells_KeyPress; // 绑定到事件  


       }  


 // 自定义事件  


       private void Cells_KeyPress(object sender, KeyPressEventArgs e)  


       {  


           if (datagridyf.CurrentCellAddress.X == 2) // 判断当前列是不是要控制的列 我是控制的索引值为2的  列(即第三列)  


           {  


               if ((Convert.ToInt32(e.KeyChar) < 48 || Convert.ToInt32(e.KeyChar) > 57) && Convert.ToInt32(e.KeyChar) != 46 && Convert.ToInt32(e.KeyChar) != 8 && Convert.ToInt32(e.KeyChar) != 13)  


               {  


                   e.Handled = true;  // 输入非法就屏蔽  


               }  


               else


               {  


                   if ((Convert.ToInt32(e.KeyChar) == 46) && (txtjg.Text.IndexOf(".") != -1))  


                   {  


                       e.Handled = true;  


                   }  


               }  


           }  


       }  


下面是在输入完成后才验证的 这个主要是在 CellValidating事件中完成  


private void datagridyf_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)  


       {  


           if (e.ColumnIndex == datagridyf.Columns["Pric"].Index )  


           {  


               datagridyf.Rows [e.RowIndex].ErrorText ="";  


               int NewVal=0;  


               if (!int.TryParse (e.FormattedValue.ToString (),out NewVal ) || NewVal <0)  


               {  


                   e.Cancel=true ;  


                   datagridyf.Rows [e.RowIndex].ErrorText ="价格列只能输入数字";  


                   return ;  


               }  


           }  


       }  


固定前两列不随着滚动条滚动。

private void Form1_Load(object sender, EventArgs e)


       {

           dataGridView1.Columns[0].Frozen = true;


           dataGridView1.Columns[1].Frozen = true;//固定前两列,滚动时,前两列的我位置不变。


           for (int i = 0; i < 10; i++)


           {

               dataGridView1.Rows.Add("11", 2, 3, 4, 5, 6, 7, 7, 8, 8, 9, 9, 9);


           }


       }


实现某一行的上下移动

/*DataGridView 实现行[Row]的上下移动,我这里用到了SelectedRows[0],而没用CurrentRow是有原因的


  主要是这两段代码:


  dataGridView1.Rows[rowIndex - 1].Selected = true;


  dataGridView1.Rows[rowIndex].Selected = false;


  这两行代码大家因该都能看懂,移上去的哪行选中状态,移下去的的取消选中状态.


  如果我用dataGridView1.CurrentRow.Cell[0].Value 他取得的值仍然是rowIndex索引行的值


   要使用SelectedRows[0] ,就必须设置这个属性:dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;


  实现原理:就是上下两行,把单元格中的值进行交换...呵呵表面上看去是向上,下移动了


*/


   private void Form3_Load(object sender, EventArgs e)


   {

     //........得到DataTable的代码省略....


    // 上移


       private void btnMoveUp_Click(object sender, EventArgs e)


       {

           // 选择的行号


           int selectedRowIndex = GetSelectedRowIndex(this.dataGridView1);


           if (selectedRowIndex >= 1)


           {

               // 拷贝选中的行


               DataGridViewRow newRow = dataGridView1.Rows[selectedRowIndex];


               // 删除选中的行


               dataGridView1.Rows.Remove(dataGridView1.Rows[selectedRowIndex]);


               // 将拷贝的行,插入到选中的上一行位置


               dataGridView1.Rows.Insert(selectedRowIndex - 1, newRow);


               // 选中最初选中的行


               dataGridView1.Rows[selectedRowIndex - 1].Selected = true;


           }


       }


  // 下移


       private void btnMoveDown_Click(object sender, EventArgs e)


       {

           int selectedRowIndex = GetSelectedRowIndex(this.dataGridView1);


           if (selectedRowIndex < dataGridView1.Rows.Count-1)


           {

               // 拷贝选中的行


               DataGridViewRow newRow = dataGridView1.Rows[selectedRowIndex];


               // 删除选中的行


               dataGridView1.Rows.Remove(dataGridView1.Rows[selectedRowIndex]);


               // 将拷贝的行,插入到选中的下一行位置


               dataGridView1.Rows.Insert(selectedRowIndex + 1, newRow);


               // 选中最初选中的行


               dataGridView1.Rows[selectedRowIndex + 1].Selected = true;


           }


       }


// 获取DataGridView中选择的行索引号


       private int GetSelectedRowIndex(DataGridView dgv)


       {

           if(dgv.Rows.Count==0)


           {

               return 0;


           }


       


           foreach(DataGridViewRow row in dgv.Rows)


           {

               if (row.Selected)


               {

                   return row.Index;


               }


           }


           return 0;


       }


      // 显示序号,行号


       private void dataGridView1_RowPostPaint(object sender,DataGridViewRowPostPaintEventArgs e)


       {

           Rectangle rectangle = new Rectangle(e.RowBounds.Location.X,


                           e.RowBounds.Location.Y,


                           dataGridView1.RowHeadersWidth - 4,


                           e.RowBounds.Height);            TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(),


               dataGridView1.RowHeadersDefaultCellStyle.Font,rectangle,


               dataGridView1.RowHeadersDefaultCellStyle.ForeColor,


               TextFormatFlags.VerticalCenter | TextFormatFlags.Right);


       }        


当前活动单元处于编辑状态的情况下检测单元格值的变化,并获取值。(DataGridView是复合控件,在编辑状态下没有办法获取到值)


实现当前活动单元格在编辑状态下获取单元格值的变化。

第一种方式:


private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)


       {


           if (this.dataGridView1.IsCurrentCellDirty == true)


           {


               this.dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);


           }


       }


       private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)


       {


           MessageBox.Show("aaaa");


       }


第二种方式:


private void dgrMenuItem_EditingControlShowing(object sender,DataGridViewEditingControlShowingEventArgs e)


{


   if (e==null ||e.Control)


       return;


   e.Control.TextChanged+=new EventHander(Control_TextChanged);


}


void Control_TextChanged(object sender,EventArgs e)


{


   MessageBox.Show(“ok”);


if (dgrMenItem.CurrentCellAdress.X==3)


{


       string val=dgrMenuItem.CurrentCell.EditedFormattedValue.ToString();


}


//另一种获取方式


Control txt=Sender as Control;


if (dgrMenItem.CurrentCellAdress.X==3)


{


   string val=txt.Text;


}


}


用下拉框来显示数据,可以修改增加,验证重复。

将DataGridView的SelectionMode设置为FullRowSelect


使用EditingControlShowing事件调用下拉框控件的事件。


private bool isInit=false;


private void dgrdThridLangage_EditingControlShowing(object sender,DataGridViewEditingControlShowingEventArgs e)


{


if (e==null|| e.Control==null)

{


   return;


}


if (e.Control is ComboBox)


{


   ComboBox cmb=e.Control as ComboBox;


   cmb.SelectedIndexChanged+=new EventHander(cmb_SelectIndexChanged);


}


}


void cmb_SelectedIndexChanged(object sender,EventArgs e)


{


   if (isInit==true)


{


   return;


}


ComboBox result=sender as ComboBox;


if (!string.IsNullOrEmpty(relust.Text))


{


   string foreignName=relust.Text;


   if (plurDic.ContainsKey(foreignName))


{


   MessageBox.Show(“已经存在,请更换语言”);


   isInit=true;//设置标志位,防止再次执行形成死循环。


   result.SelectedIndex=-1;


   isInit=false;


return;


}


}


}


在DatGridView的表头添加一个复选框,实现列的全选和全清。

tt.png

public partial class Form1 : Form


   {


       CheckBox HeaderCheckBox = null;


       public Form1()


       {


           InitializeComponent();


           if (!this.DesignMode)


           {


               HeaderCheckBox = new CheckBox();


               HeaderCheckBox.Size = new Size(15, 15);


               HeaderCheckBox.Text = "";


               this.dataGridView1.Controls.Add(HeaderCheckBox);


               HeaderCheckBox.CheckedChanged += HeaderCheckBox_CheckedChanged;


               dataGridView1.CellPainting += DataGridView1_CellPainting;


           }


           AddData();


       }


       private void AddData()


       {


           for (int i = 0; i < 10; i++)


           {


               dataGridView1.Rows.Add(false, "2", "3", "4");


           }


       }


       private void DataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)


       {


           if (e.RowIndex == -1 && e.ColumnIndex == 4)


           {


               ResetHeaderCheckBoxLocation(e.ColumnIndex, e.RowIndex);


           }


       }


       private void HeaderCheckBox_CheckedChanged(object sender, EventArgs e)


       {


           HeaderCheckBoxClick((CheckBox)sender);


       }


       private void HeaderCheckBoxClick(CheckBox checkBox)


       {


           foreach (DataGridViewRow row in dataGridView1.Rows)


           {


               ((DataGridViewCheckBoxCell)row.Cells[0]).Value = HeaderCheckBox.Checked;


           }


           dataGridView1.RefreshEdit();


       }


       private void ResetHeaderCheckBoxLocation(int columnIndex, int rowIndex)


       {


           Rectangle rectangle = this.dataGridView1.GetCellDisplayRectangle(columnIndex, rowIndex, true);


           Point point = new Point(rectangle.Location.X + 3, rectangle.Location.Y + 3);


           HeaderCheckBox.Location = point;


       }


   }


}


给下拉列绑定数据

tt.png

思路:声明个全局的字典类型的集合,将数据放到集合里,数据的Name作为字典的key,ID作为字典的value,将Name添加到列中。


      Dictionary<string, string> dic = new Dictionary<string, string>();


   


       private void button1_Click(object sender, EventArgs e)


       {


           dic.Add("AA", "OA");


           dic.Add("BB", "HH");


           DataGridViewComboBoxColumn cmbDep = (DataGridViewComboBoxColumn)dataGridView1.Columns[0];


           foreach (string name in dic.Keys)


           {


               if (!cmbDep.Items.Contains(name))


               {


                   cmbDep.Items.Add(name);


               }


           }


       }


对DataGridView单元格进行进行验证,验证错误后焦点不离开

思路:


单元格验证使用CellValidating事件。验证不通过时调用e.Cancel=true;终止事件链,但愿将保持编辑状态。


调用DataGridView.CancelEdit;可以使单元格的内容回滚到修改前的值。使用System.Windows.Forms.SendKey.Send(“^a”);全选单元格的内容。


代码:


private void dataGridView1_CellValidating(object sender,DataGridViewCellValidatingEventArgs e)


{

        if (e.RowIndex<0)


                  return;


        if (e.ColumnIndex!=2)


                  return;//不是验证的列不执行


        bool isTrue=false;


//验证逻辑


if(b==false)//表示验证没有通过


{

        MessageBox.show(“没有通过验证”);


        e.Cancel=true;


        dataGridView1.CancelEdit();


        dataGridView1.CurrentCell=dataGridView1[e.ColumnIndex,e.RowIndex];


        dataGridView1.BeginEdit(false);


}


}


操作DataGridView中的Button列

private void dataGridView1_CellContentClick(object sender,DataGridViewCellEventArgs e)


{

        if (dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].GetType()==typeof(DataGridViewButtonCell))


{dataGridView1.Rows.RemoveAt(e.RowIndex);}


}


将DataGridView转换为DataTable

在DataGridView的DataSource是DataTable的时候直接赋值即可


在DataGridView通过遍历的方式填进去的数据时,没有Datasource 或者DataSource不是DataTable类型的时候使用下面这种方式。


 public System.Data.DataTable GetDataTable(DataGridView dataGridView)


       {


           System.Data.DataTable dt = new System.Data.DataTable();


           for (int count = 0; count < dataGridView.ColumnCount; count++)


           {


               DataColumn dataColumn = new DataColumn(dataGridView1.Columns[count].Name.ToString());


               dt.Columns.Add(dataColumn);


           }


           for (int count = 0; count < dataGridView1.Columns.Count; count++)


           {


               DataRow dr = dt.NewRow();


               for (int countsub = 0; countsub < dataGridView.Columns.Count; countsub++)


               {


                   dr[countsub] = Convert.ToString(dataGridView.Rows[count].Cells[countsub].Value);


               }


               dt.Rows.Add(dr);


           }


           return dt;


       }


数据随着鼠标的滚轴滚轴上下移动。

用到的事件是MouseWheel事件。


dataGridView.MouseWheel+=new MouseEventHandler(dataGridView_MouseWheel);


dataGridView.TabIndex=0;


void dataGridView_MouseWheel(object sender,MouseEventArgs e)


{

        if (dataGridView.RowCount>dataGridView.DisplayRowCount(false))


{

        int index=dataGridView.FirstDisplayScrollingRowIndex;


        if (e.Delta>0)


        {

                  if (index>0)


                  {

                           dataGridView.FirstDisplayScrollingRowIndex=index-1;


}


}


else


{

        if(index<dataGridView.Row.Count-1)


        {

                  dataGridView.FirstDisplayScrollingRowIndex=index+1;


}


}


}


}


多维表头

tt.png

新建组件,写TreeHeadDataGridView.cs


using System;


using System.ComponentModel;


using System.Collections.Generic;


using System.Diagnostics;


using System.Text;


using System.Windows.Forms;


using System.Collections;


using System.Drawing;



namespace CellPaintingDataGridView


{


   public partial class TreeHeadDataGridView : DataGridView


   {


       private TreeView treeView1=new TreeView();


       public TreeHeadDataGridView()


       {


           InitializeComponent();


       }


       public TreeHeadDataGridView(IContainer container)


       {


           container.Add(this);


           InitializeComponent();


       }


       [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]


       public TreeNodeCollection HeadSource


       {


           get { return this.treeView1.Nodes; }


       }


       private int _cellHeight = 17;


       private int _columnDeep = 1;


       [Description("设置或获得合并表头树的深度")]


       public int ColumnDeep


       {


           get


           {


               if (this.Columns.Count == 0)


                   _columnDeep = 1;


               this.ColumnHeadersHeight = _cellHeight * _columnDeep;


               return _columnDeep;


           }


           set


           {


               if (value < 1)


                   _columnDeep = 1;


               else


                   _columnDeep = value;


               this.ColumnHeadersHeight = _cellHeight * _columnDeep;


           }


       }


       ///<summary>


       ///绘制合并表头


       ///</summary>


       ///<param name="node">合并表头节点</param>


       ///<param name="e">绘图参数集</param>


       ///<param name="level">结点深度</param>


       ///<remarks></remarks>


       public void PaintUnitHeader(TreeNode node, DataGridViewCellPaintingEventArgs e, int level)


       {


           //根节点时退出递归调用


           if (level == 0)


               return;


           RectangleF uhRectangle;


           int uhWidth;


           SolidBrush gridBrush = new SolidBrush(this.GridColor);


           Pen gridLinePen = new Pen(gridBrush);


           StringFormat textFormat = new StringFormat();


           textFormat.Alignment = StringAlignment.Center;


           uhWidth = GetUnitHeaderWidth(node);


           //与原贴算法有所区别在这。


           if (node.Nodes.Count == 0)


           {


               uhRectangle = new Rectangle(e.CellBounds.Left,


                           e.CellBounds.Top + node.Level * _cellHeight,


                           uhWidth - 1,


                           _cellHeight * (_columnDeep - node.Level) - 1);


           }


           else


           {


               uhRectangle = new Rectangle(


                           e.CellBounds.Left,


                           e.CellBounds.Top + node.Level * _cellHeight,


                           uhWidth - 1,


                           _cellHeight - 1);


           }


           Color backColor = e.CellStyle.BackColor;


           if (node.BackColor != Color.Empty)


           {


               backColor = node.BackColor;


           }


           SolidBrush backColorBrush = new SolidBrush(backColor);


           //画矩形


           e.Graphics.FillRectangle(backColorBrush, uhRectangle);


           //划底线


           e.Graphics.DrawLine(gridLinePen


                               , uhRectangle.Left


                               , uhRectangle.Bottom


                               , uhRectangle.Right


                               , uhRectangle.Bottom);


           //划右端线


           e.Graphics.DrawLine(gridLinePen


                               , uhRectangle.Right


                               , uhRectangle.Top


                               , uhRectangle.Right


                               , uhRectangle.Bottom);


           写字段文本


           Color foreColor = Color.Black;


           if (node.ForeColor != Color.Empty)


           {


               foreColor = node.ForeColor;


           }


           e.Graphics.DrawString(node.Text, this.Font


                                   , new SolidBrush(foreColor)


                                   , uhRectangle.Left + uhRectangle.Width / 2 -


                                   e.Graphics.MeasureString(node.Text, this.Font).Width / 2 - 1


                                   , uhRectangle.Top +


                                   uhRectangle.Height / 2 - e.Graphics.MeasureString(node.Text, this.Font).Height / 2);


           递归调用()


           if (node.PrevNode == null)


               if (node.Parent != null)


                   PaintUnitHeader(node.Parent, e, level - 1);


       }


       /// <summary>


       /// 获得合并标题字段的宽度


       /// </summary>


       /// <param name="node">字段节点</param>


       /// <returns>字段宽度</returns>


       /// <remarks></remarks>


       private int GetUnitHeaderWidth(TreeNode node)


       {


           //获得非最底层字段的宽度


           int uhWidth = 0;


           //获得最底层字段的宽度


           if (node.Nodes == null)


               return this.Columns[GetColumnListNodeIndex(node)].Width;


           if (node.Nodes.Count == 0)


               return this.Columns[GetColumnListNodeIndex(node)].Width;


           for (int i = 0; i <= node.Nodes.Count - 1; i++)


           {


               uhWidth = uhWidth + GetUnitHeaderWidth(node.Nodes[i]);


           }


           return uhWidth;


       }


       /// <summary>


       /// 获得底层字段索引


       /// </summary>


       /// <param name="node">底层字段节点</param>


       /// <returns>索引</returns>


       /// <remarks></remarks>


       private int GetColumnListNodeIndex(TreeNode node)


       {


           for (int i = 0; i <= _columnList.Count - 1; i++)


           {


               if (((TreeNode)_columnList[i]).Equals(node))


                   return i;


           }


           return -1;


       }


       private List<TreeNode> _columnList = new List<TreeNode>();


       [Description("最底層結點集合")]


       public List<TreeNode> NadirColumnList


       {


           get


           {


               if (this.treeView1 == null)


                   return null;


               if (this.treeView1.Nodes == null)


                   return null;


               if (this.treeView1.Nodes.Count == 0)


                   return null;


               _columnList.Clear();


               foreach (TreeNode node in this.treeView1.Nodes)


               {


                   //GetNadirColumnNodes(_columnList, node, false);


                   GetNadirColumnNodes(_columnList, node);


               }


               return _columnList;


           }


       }


       private void GetNadirColumnNodes(List<TreeNode> alList, TreeNode node)


       {


           if (node.FirstNode == null)


           {


               alList.Add(node);


           }


           foreach (TreeNode n in node.Nodes)


           {


               GetNadirColumnNodes(alList, n);


           }


       }


       /// <summary>


       /// 获得底层字段集合


       /// </summary>


       /// <param name="alList">底层字段集合</param>


       /// <param name="node">字段节点</param>


       /// <param name="checked">向上搜索与否</param>


       /// <remarks></remarks>


       private void GetNadirColumnNodes(List<TreeNode> alList, TreeNode node, Boolean isChecked)


       {


           if (isChecked == false)


           {


               if (node.FirstNode == null)


               {


                   alList.Add(node);


                   if (node.NextNode != null)


                   {


                       GetNadirColumnNodes(alList, node.NextNode, false);


                       return;


                   }


                   if (node.Parent != null)


                   {


                       GetNadirColumnNodes(alList, node.Parent, true);


                       return;


                   }


               }


               else


               {


                   if (node.FirstNode != null)


                   {


                       GetNadirColumnNodes(alList, node.FirstNode, false);


                       return;


                   }


               }


           }


           else


           {


               if (node.FirstNode == null)


               {


                   return;


               }


               else


               {


                   if (node.NextNode != null)


                   {


                       GetNadirColumnNodes(alList, node.NextNode, false);


                       return;


                   }


                   if (node.Parent != null)


                   {


                       GetNadirColumnNodes(alList, node.Parent, true);


                       return;


                   }


               }


           }


       }


       /// <summary>


       /// 单元格绘制(重写)


       /// </summary>


       /// <param name="e"></param>


       /// <remarks></remarks>


       protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)


       {


           //行标题不重写


           if (e.ColumnIndex < 0)


           {


               base.OnCellPainting(e);


               return;


           }


           if (_columnDeep == 1)


           {


               base.OnCellPainting(e);


               return;


           }


           //绘制表头


           if (e.RowIndex == -1)


           {


               PaintUnitHeader((TreeNode)NadirColumnList[e.ColumnIndex], e, _columnDeep);


               e.Handled = true;


           }


       }


   }


}


然后就可以在工具框里看到刚才写的组件了





将其拖入窗体,点开HeadSource增加表头

tt.png

 private void Form1_Load(object sender, EventArgs e)


   {


           TreeNode node=new TreeNode();


           node.Text="wh";


           treeHeadDataGridView1.HeadSource.Add(node);


    }


添加合计行

添加合计行支持行的左右拖动,支持鼠标滚轴。


tt.png
tt.png


布局:


tt.png


思路:


数据部分的DataGridView不带任何滚动框

合计部分的DataGridView带有横向滚动框

在画面上添加一个纵向滚动框vscrollBar1

实现思路就是用合计行的横向滚动框控制两个DataGridView的横向滚动,右侧的纵向滚动框控制数据部分的DataGridView,效果开起来就是合计行始终显示在底部。


页面设计:


把数据展示区和数据合计区的DataGridView放到一个DateGridView中。合计区的高度为40个像素。

数据区的DataGridView设置:

DataGridView1.AllowUserToAddRows=False;


DataGridView1.ScroBars=None;


DataGridView1.SelectionMode=DataGridViewsSelectionMode.FullRowSelect;


DataGridView1.ColumnWidthChanged+=new DataGridViewColumnEventHandler(DataGridView1_ColumnWidthChanged);


数据合计区的设置。

DataGridViewSum. AllowUserToAddRows=False;


DataGridViewSum.AllowUserToResizeColumns=False;//列不能拖动


DataGridViewSum.Anchor=Buttom,Left,Right;


DataGridViewSum.ColumnHeadersHeightSizeMode=System.Windows.Forms.DataGridViewColumnHeader.HeightSizeMode.AutoSize;


DataGridViewSum.ColumnsHeadersVisible=false;


DataGridViewSum.ReadOnly=true;


DataGridViewSum.ScrollBars=System.Windows.Forms.ScrollBars.Horizontal;


vscrollBar1控件的设置

vscrollBar1.Anchor=Top,Button,Right;


this. vscrollBar1.visibleChanged+=new System.EventHander(vscrollBar1_VisibleChanged);


this. vscrollBar1.Scroll+=new System.Windows.Forms.ScrollEventHandler(vscrollBar1_Scroll);


代码:


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 WindowsFormsApplication11


{


   public partial class Form1 : Form


   {


       public Form1()


       {


           InitializeComponent();


       }


       private DataTable dt = new DataTable();


       private DataTable dtSum;


 


       private int Row_Height = 21;


       private void Form1_Load(object sender, EventArgs e)


       {


           VScrollBar1.Visible = false;


       }


       private void kButton1_Click(object sender, EventArgs e)


       {


           dt = GetData();


           this.kDataGridView1.AutoGenerateColumns = false;


           this.kDataGridView1.DataSource = dt;


           this.kDataGridView1.Columns[0].DataPropertyName = dt.Columns[0].ColumnName;


           this.kDataGridView1.Columns[1].DataPropertyName = dt.Columns[1].ColumnName;


           this.kDataGridView1.Columns[2].DataPropertyName = dt.Columns[2].ColumnName;


           this.kDataGridView1.Columns[3].DataPropertyName = dt.Columns[3].ColumnName;


           this.kDataGridView1.Columns[4].DataPropertyName = dt.Columns[4].ColumnName;


           this.kDataGridView1.Columns[5].DataPropertyName = dt.Columns[5].ColumnName;


           this.kDataGridView1.Columns[6].DataPropertyName = dt.Columns[6].ColumnName;


           this.kDataGridView1.Columns[7].DataPropertyName = dt.Columns[7].ColumnName;


           this.kDataGridView1.Columns[8].DataPropertyName = dt.Columns[8].ColumnName;


           this.kDataGridView1.Columns[9].DataPropertyName = dt.Columns[9].ColumnName;    


           this.kDataGridView1.RowTemplate.Height = Row_Height;


           GetSumData();


           if (kDataGridView1.RowCount > kDataGridView1.DisplayedRowCount(false))


           {


               VScrollBar1.Visible = true;


               VScrollBar1.Maximum = (this.kDataGridView1.Rows.Count - this.kDataGridView1.DisplayedRowCount(false)) * Row_Height;


               VScrollBar1.Minimum = 0;


               VScrollBar1.SmallChange = 21;


               VScrollBar1.LargeChange = 50;


           }


       }


       private DataTable GetData()


       {


           DataTable dtData = new DataTable("TEST");


          DataRow dr ;


           dt.Columns.Add(new DataColumn("号码", typeof(String)));


           dt.Columns.Add(new DataColumn("数量1", typeof(int)));


           dt.Columns.Add(new DataColumn("数量2", typeof(int)));


           dt.Columns.Add(new DataColumn("数量3", typeof(int)));


           dt.Columns.Add(new DataColumn("数量4", typeof(int)));


           dt.Columns.Add(new DataColumn("数量5", typeof(int)));


           dt.Columns.Add(new DataColumn("数量6", typeof(int)));


           dt.Columns.Add(new DataColumn("数量7", typeof(int)));


           dt.Columns.Add(new DataColumn("数量8", typeof(int)));


           dt.Columns.Add(new DataColumn("数量9", typeof(int)));


           Random rdm = new Random();


           for (int i = 10; i < 80; i++)


           {


               dr = dt.NewRow();


               dr[0] = ("00" + i).ToString();


               for (int j = 1; j < 10; j++)


               {


                   dr[j] = rdm.Next(1000, 5000);


               }


               dt.Rows.Add(dr);


           }


           return dt;


       }


       private void GetSumData()


       {


           DataRow dr;


           dtSum = new DataTable("TEST");


           dtSum = dt.Clone();


           Random rdm = new Random();


           dr = dtSum.NewRow();


           dr[0] = "合计";


           for (int i = 1; i < dt.Columns.Count - 1; i++)


           {


               dr[i] = dt.Compute("Sum(" + dt.Columns[i].ColumnName + ")", "true");


           }


           dtSum.Rows.Add(dr);


           this.kDataGridView2.AutoGenerateColumns = false;


           this.kDataGridView2.DataSource = dtSum;


           this.kDataGridView2.Columns[0].DataPropertyName = dtSum.Columns[0].ColumnName;


           this.kDataGridView2.Columns[1].DataPropertyName = dtSum.Columns[1].ColumnName;


           this.kDataGridView2.Columns[2].DataPropertyName = dtSum.Columns[2].ColumnName;


           this.kDataGridView2.Columns[3].DataPropertyName = dtSum.Columns[3].ColumnName;


           this.kDataGridView2.Columns[4].DataPropertyName = dtSum.Columns[4].ColumnName;


           this.kDataGridView2.Columns[5].DataPropertyName = dtSum.Columns[5].ColumnName;


           this.kDataGridView2.Columns[6].DataPropertyName = dtSum.Columns[6].ColumnName;


           this.kDataGridView2.Columns[7].DataPropertyName = dtSum.Columns[7].ColumnName;


           this.kDataGridView2.Columns[8].DataPropertyName = dtSum.Columns[8].ColumnName;


           this.kDataGridView2.Columns[9].DataPropertyName = dtSum.Columns[9].ColumnName;


           this.kDataGridView2.Rows[0].DefaultCellStyle.BackColor = Color.Red;


           this.kDataGridView2.ReadOnly = true;


           this.kDataGridView2.SelectionMode = DataGridViewSelectionMode.FullRowSelect;


       }


       private void kDataGridView2_Scroll(object sender, ScrollEventArgs e)


       {


           this.kDataGridView1.HorizontalScrollingOffset = e.NewValue;


       }


       private void VScrollBar1_Scroll(object sender, ScrollEventArgs e)


       {


           this.kDataGridView1.FirstDisplayedScrollingRowIndex = e.NewValue / Row_Height ;


       }


       private void kDataGridView2_CellContentClick(object sender, DataGridViewCellEventArgs e)


       {


       


       }


       private void kDataGridView1_RowHeadersWidthChanged(object sender, EventArgs e)


       {


     


       }


       private void kDataGridView1_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)


       {


           for (int i = 0; i < kDataGridView1.ColumnCount; i++)


           {


               kDataGridView2.Columns[i].Width = kDataGridView1.Columns[i].Width;


           }


       }


   


   }


}


 


目录
相关文章
|
10月前
|
存储 缓存 C#
46.c#:datagridview控件
46.c#:datagridview控件
133 1
|
SQL 存储 Go
WinForm DataGridView分页功能
WinForm 里面的DataGridView不像WebForm里面的GridView那样有自带的分页功能,需要自己写代码来实现分页,效果如下图: 分页控件   .CS: 1 using System; 2 using System.
1446 0
|
数据可视化 数据库 图形学
WinForm——ComboBox总结
WinForm——ComboBox总结
579 0
WinForm——ComboBox总结
WinForm——TreeView总结
WinForm——TreeView总结
472 0