天天看点

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;

实现某一列只能输入数字

最近在开发一个项目时,要求某一列只能够输入数字,其它的字符都不接受,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)

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

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

               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)

       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;

   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)

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的表头添加一个复选框,实现列的全选和全清。

WinForm——DataGridView总结

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()

               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;

   }

给下拉列绑定数据

WinForm——DataGridView总结

思路:声明个全局的字典类型的集合,将数据放到集合里,数据的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;

多维表头

WinForm——DataGridView总结

新建组件,写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()

       public TreeHeadDataGridView(IContainer container)

           container.Add(this);

       [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)

               else

                   _columnDeep = value;

       ///<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,

                           _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);

           //划右端线

                               , uhRectangle.Top

           写字段文本

           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;

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

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

           return uhWidth;

       /// 获得底层字段索引

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

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

       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

               if (this.treeView1 == null)

                   return null;

               if (this.treeView1.Nodes == null)

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

               _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);

       /// 获得底层字段集合

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

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

       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);

                   if (node.FirstNode != null)

                       GetNadirColumnNodes(alList, node.FirstNode, false);

                   return;

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

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

       protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)

           //行标题不重写

           if (e.ColumnIndex < 0)

               base.OnCellPainting(e);

           if (_columnDeep == 1)

           //绘制表头

           if (e.RowIndex == -1)

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

               e.Handled = true;

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

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

WinForm——DataGridView总结

  private void Form1_Load(object sender, EventArgs e)

           TreeNode node=new TreeNode();

           node.Text="wh";

           treeHeadDataGridView1.HeadSource.Add(node);

    }

添加合计行

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

WinForm——DataGridView总结

布局:

WinForm——DataGridView总结

数据部分的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.Data;

using System.Linq;

namespace WindowsFormsApplication11

   public partial class Form1 : Form

       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);

       private void GetSumData()

           DataRow dr;

           dtSum = new DataTable("TEST");

           dtSum = dt.Clone();

           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;

继续阅读