- 常用属性
- 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的表头添加一个复选框,实现列的全选和全清。
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;
}
}
}
- 给下拉列绑定数据
思路:声明个全局的字典类型的集合,将数据放到集合里,数据的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;
}
}
}
}
- 多维表头
新建组件,写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增加表头
private void Form1_Load(object sender, EventArgs e)
{
TreeNode node=new TreeNode();
node.Text=”wh”;
treeHeadDataGridView1.HeadSource.Add(node);
}
- 添加合计行
添加合计行支持行的左右拖动,支持鼠标滚轴。
布局:
思路:
- 数据部分的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;
}
}
}
}
今天的文章WinForm——DataGridView总结分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/18448.html