




















































































































































































































































































































































































































































































































































































































































































































































































































dot net 2005 提供了datagridview 这个控件,但是总感觉不好使,尤其当想在datagridview中显示combobox,checkbox时,并把结果写到数据库时总是感觉不太方便,于是决定自己改写datagrid自己加入combobox,checkbox
我把两个类封装在XUIControls包中了,提供了XUIControl.dll供大家使用
下面说说如何 定制自己的datagrid风格
一。 打开dot net(2005 or 2003 2005中好像找不到datagrid控件 需要自己new个
1. 文件--〉新建--〉项目 选择 visual c# |类库 文件名定义为XUIControls
2. 选中XUIControls 项目右键 添加新项 选择c# 类文件,命名DataGridComboBoxColumnStyle.cs(如果想定制checkbox,可以命名为DataGridCheckBoxColumnStyle.cs,其它类似)
3.打开DataGridComboBoxColumnStyle.cs文件 添加代码:
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace XUIControls
{
public partial class DataGridComboBoxColumnStyle : System.Windows.Forms.DataGridColumnStyle
{
private ComboBox X_ComboBox = new ComboBox();//define new component
private bool IsEditing;
public DataGridComboBoxColumnStyle(IContainer container)
{
container.Add(this);//add this component to container
InitializeComponent();// initialize the component
}
//the default construct fuction
public DataGridComboBoxColumnStyle(): base()
{
// TODO: Add constructor logic here
X_ComboBox.Visible = false;// the default setting is unvisible
}
/* 备注
当 DataGridColumnStyle 方法的 Commit 方法返回 false 时,Abort 方法被 DataGrid 使用。在这种情况 下,列值滚动回原先的值。
在返回之前,DataGridColumnStyle 必须结束所有编辑操作。使用 Abort 方法来实现该操作。
System.Windows.Forms.DataGrid 控件的 EndEdit 方法间接调用 Abort(如果其 ShouldAbort 参数设置为 true)。
*/
protected override void Abort(int rowNum)
{ // this method override the parent's method.
//when it is invoked,it will originate an request to interrupt the edite.
IsEditing = false;// set the component unedited.
X_ComboBox.Click -= new EventHandler(this.ComboBoxValueChanged);//remove the dispose fuction
Invalidate();//constrain or enforce the component repainted.
}
/*在派生类中被重写时,将启动一个请求来完成编辑过程。
参数
dataSource DataGridColumnStyle 的 CurrencyManager。
rowNum 所编辑行的行号。
返回值 如果编辑过程成功提交,则为 true;否则为 false。
备注
对继承者的说明: Commit 方法应该由从 DataGridColumnStyle 类中派生的类使用以重设它们的编辑状态,例如,如果 DataGridColumnStyle 承载一个编辑控件,可以放弃焦点。请参见 ConcedeFocus 方法。
在 DataGridColumnStyle 收到完成编辑的请求时调用 Commit 方法。如果在没有错误的情况下不能完成此操作,则返回 false。
Commit 方法由 System.Windows.Forms.DataGrid 控件的公共方法 OnMouseDown 调用。该方法也可以由其他私有方法来调用,例如在更改当前行时。
*/
protected override bool Commit(CurrencyManager dataSource, int rowNum)
{
X_ComboBox.Bounds = Rectangle.Empty;
X_ComboBox.Click -= new EventHandler(this.ComboBoxValueChanged);
if (!IsEditing)
return true;
IsEditing = false;
try
{
string value = X_ComboBox.Text;
SetColumnValueAtRow(dataSource, rowNum, value);
}
catch (Exception)
{
Abort(rowNum);
return false;
}
Invalidate();
return true;
}
protected override void Edit(CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible)
{
string value = (string)GetColumnValueAtRow(source, rowNum);
if (cellIsVisible)
{
X_ComboBox.Bounds = new Rectangle
(bounds.X + 2, bounds.Y + 2, bounds.Width - 4, bounds.Height - 4);
X_ComboBox.Text = value;
X_ComboBox.Visible = true;
X_ComboBox.Click += new EventHandler(this.ComboBoxValueChanged);
}
else
{
X_ComboBox.Text = value;
X_ComboBox.Visible = false;
}
if (X_ComboBox.Visible)
DataGridTableStyle.DataGrid.Invalidate(bounds);
}
protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum)
{
Paint(g, bounds, source, rowNum, false);
}
protected override void Paint( Graphics g,Rectangle bounds,CurrencyManager source,int rowNum,
bool alignToRight)
{
Paint(
g, bounds,
source,
rowNum,
Brushes.Red,
Brushes.Blue,
alignToRight);
}
protected override void Paint(
Graphics g,
Rectangle bounds,
CurrencyManager source,
int rowNum,
Brush backBrush,
Brush foreBrush,
bool alignToRight)
{
string date = (string)
GetColumnValueAtRow(source, rowNum);
Rectangle rect = bounds;
g.FillRectangle(backBrush, rect);
rect.Offset(0, 2);
rect.Height -= 2;
g.DrawString(date, this.DataGridTableStyle.DataGrid.Font, foreBrush, rect);
//g.DrawString(date,this.DataGridTableStyle.DataGrid.Font,foreBrush,rect.X,rect.Y); //ok
}
protected override Size GetPreferredSize(Graphics g, object value)
{
return new Size(100, 24);
}
protected override int GetMinimumHeight()
{
return 24;
}
protected override int GetPreferredHeight(Graphics g, object value)
{
return 24;
}
protected override void SetDataGridInColumn(DataGrid value)
{
base.SetDataGridInColumn(value);
if (X_ComboBox.Parent != null)
{
X_ComboBox.Parent.Controls.Remove(X_ComboBox);
}
if (value != null)
{
value.Controls.Add(X_ComboBox);
}
}
private void ComboBoxValueChanged(object sender, EventArgs e)
{
this.IsEditing = true;
base.ColumnStartedEditing(X_ComboBox);
}
public void AddItem(string StrItemName)
{
X_ComboBox.Items.Add(StrItemName);
}
}
}
具体函数的意思可以查阅msdn ,这里就不说了,此外代码中可能有中文空格或标点不能直接复制到.net
请使用原文件
如果想增加checkbox,可以新添新项DataGridCheckBoxColumnStyle.cs
添加代码
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows.Forms;
using System.Drawing;
namespace XUIControls
{
public partial class DataGridCheckBoxColumnStyle : System.Windows.Forms.DataGridColumnStyle
{
private CheckBox X_CheckBox = new CheckBox();//define new component
//private bool IsEditing;
public DataGridCheckBoxColumnStyle(IContainer container)
{
container.Add(this);//add this component to container
// InitializeComponent();// initialize the component
}
//the default construct fuction
public DataGridCheckBoxColumnStyle(): base()
{
// TODO: Add constructor logic here
X_CheckBox.Visible = false;// the default setting is unvisible
}
/* 备注
当 DataGridColumnStyle 方法的 Commit 方法返回 false 时,Abort 方法被 DataGrid 使用。在这种情况下,列值滚动回原先的值。
在返回之前,DataGridColumnStyle 必须结束所有编辑操作。使用 Abort 方法来实现该操作。
System.Windows.Forms.DataGrid 控件的 EndEdit 方法间接调用 Abort(如果其 ShouldAbort 参数设置为 true)。
*/
protected override void Abort(int rowNum)
{ // this method override the parent's method.
//when it is invoked,it will originate an request to interrupt the edite.
//IsEditing = false;// set the component unedited.
X_CheckBox.Click -= new EventHandler(this.CheckedChanged);//remove the dispose fuction
Invalidate();//constrain or enforce the component repainted.
}
/*在派生类中被重写时,将启动一个请求来完成编辑过程。
参数
dataSource DataGridColumnStyle 的 CurrencyManager。
rowNum 所编辑行的行号。
返回值 如果编辑过程成功提交,则为 true;否则为 false。
备注
对继承者的说明: Commit 方法应该由从 DataGridColumnStyle 类中派生的类使用以重设它们的编辑状态,例如,如果 DataGridColumnStyle 承载一个编辑控件,可以放弃焦点。请参见 ConcedeFocus 方法。
在 DataGridColumnStyle 收到完成编辑的请求时调用 Commit 方法。如果在没有错误的情况下不能完成此操作,则返回 false。
Commit 方法由 System.Windows.Forms.DataGrid 控件的公共方法 OnMouseDown 调用。该方法也可以由其他私有方法来调用,例如在更改当前行时。
*/
protected override bool Commit(CurrencyManager dataSource, int rowNum)
{
X_CheckBox.Bounds = Rectangle.Empty;
X_CheckBox.Click -= new EventHandler(this.CheckedChanged);
// if (!IsEditing)
// return true;
// IsEditing = false;
try
{
string value = X_CheckBox.Text;
if (X_CheckBox.Checked)
value = "Y";
else
value = "N";
SetColumnValueAtRow(dataSource, rowNum, value);
}
catch (Exception)
{
Abort(rowNum);
return false;
}
Invalidate();
return true;
}
protected override void Edit(CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible)
{
string value = (string)GetColumnValueAtRow(source, rowNum);
X_CheckBox.Bounds = new Rectangle(bounds.X + 2, bounds.Y + 2, bounds.Width - 4, bounds.Height - 4);
X_CheckBox.Text = value;
X_CheckBox.Visible = true;
X_CheckBox.Click += new EventHandler(this.CheckedChanged);
if (X_CheckBox.Visible)
DataGridTableStyle.DataGrid.Invalidate(bounds);
}
protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum)
{
Paint(g, bounds, source, rowNum, false);
}
protected override void Paint( Graphics g, Rectangle bounds, CurrencyManager source, int rowNum,bool alignToRight)
{
Paint(g, bounds,source,rowNum,Brushes.Red,Brushes.Blue,alignToRight);
}
protected override void Paint(Graphics g,Rectangle bounds,CurrencyManager source,
int rowNum,Brush backBrush,Brush foreBrush,bool alignToRight)
{
string date = (string)GetColumnValueAtRow(source, rowNum);
Rectangle rect = bounds;
g.FillRectangle(backBrush, rect);
rect.Offset(0, 2);
rect.Height -= 2;
g.DrawString(date, this.DataGridTableStyle.DataGrid.Font, foreBrush, rect);
//g.DrawString(date,this.DataGridTableStyle.DataGrid.Font,foreBrush,rect.X,rect.Y); //ok
}
protected override Size GetPreferredSize(Graphics g, object value)
{
return new Size(100, 24);
}
protected override int GetMinimumHeight()
{
return 24;
}
protected override int GetPreferredHeight(Graphics g, object value)
{
return 24;
}
protected override void SetDataGridInColumn(DataGrid value)
{
base.SetDataGridInColumn(value);
if (X_CheckBox.Parent != null)
{
X_CheckBox.Parent.Controls.Remove(X_CheckBox);
}
if (value != null)
{
value.Controls.Add(X_CheckBox);
}
}
private void CheckedChanged(object sender, EventArgs e)
{
checkeditem();
base.ColumnStartedEditing(X_CheckBox);
}
public bool getchecked( )
{
if (X_CheckBox.Checked)
return true;
else
return false;
}
private void checkeditem()
{
if (X_CheckBox.Checked)
X_CheckBox.Text = "Y";
else
X_CheckBox.Text = "N";
}
}
}
其实两个类的代码类似,如果你想添加其它的控件也可以用类似的方法,注意在 X_CheckBox.Click += new EventHandler(this.CheckedChanged); 添加自己欲使用的事件,并且在下面一定要定义这个处理函数
当然也可以添加其它函数,比如设置文本显示,大小,颜色风格等,传值。
4。接下来要做的就是生成.dll,因为没有main()所以是不能执行的,编译后会提示
警告 1 设计器必须创建类型“System.Windows.Forms.DataGridColumnStyle”的实例,但该类型已声明为抽象,因此设计器无法创建该类型的实例。 0 0
这已经成功了,如果有别的错误,那就有问题了需要修改。
然后会在debug文件夹中找到 XUIControls.dll,以后就可以引用它了。
二。使用自定义风格的datagrid
//----------------------------------------------------------------------------------------------------------------------------------------------
1. new project->c# project->choose [the windows applications ]->projectname: NewDataGrid
then we have builded the new c# project NewDataGrid
next
2. open the project and add a datagrid component to the panel. you may can't find it in dot net 2005 .
you have to new a datagrid and modify the designer to add it. if in dotnet2003 ,no problem.then next
3 .if you are in dot net2003 ,add a datagrid from the component panel to the workarea and
skip to the next step. when in dot net 2005,we must do :
open the FROM1.DESIGNER.CS (choose the FUn:InitializeComponent(),then skip to the definiton)
add " this.dataGrid1 = new System.Windows.Forms.DataGrid();"
"((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).BeginInit();"
and set the style:
this.dataGrid1.CaptionText = "adsfsadfsadf";
this.dataGrid1.DataMember = "";
this.dataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText;
this.dataGrid1.Location = new System.Drawing.Point(12, 12);
this.dataGrid1.Name = "dataGrid1";
this.dataGrid1.Size = new System.Drawing.Size(407, 260);
this.dataGrid1.TabIndex = 1;
and add the control-----
this.Controls.Add(this.dataGrid1);
((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).EndInit();
----------- in the bottom in the function
now it's ok
//---------------------------------------------------------------------------------------------------------------------------------------------------
please review the source file if you have any problems;
the form1.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using XUIControls;// 注意增加引用XUIControls.dll,然后增加该语句
namespace NewDataGrid
{
public partial class Form1 : Form
{
// private XUIControls.DataGridComboBoxColumnStyle userhead;
private System.Windows.Forms.DataGrid dataGrid1;
XUIControls.DataGridCheckBoxColumnStyle chkStyle;// 创建实例
DataGridTextBoxColumn nameColumnStyle;
private DataTable namesDataTable;
public Form1()
{
InitializeComponent();
//--------------------------------------------------------------------------------------
namesDataTable = new DataTable("NamesTable");
dataGrid1.Enabled = true;
namesDataTable.Columns.Add(new DataColumn("Name"));
namesDataTable.Columns.Add(new DataColumn("State"));
namesDataTable.Columns.Add(new DataColumn("Date"));
DataSet namesDataSet = new DataSet();
namesDataSet.Tables.Add(namesDataTable);
AddData();
this.dataGrid1.DataSource = namesDataSet;
this.dataGrid1.DataMember = "NamesTable";
AddGridStyle();
}
private void AddData()
{
DataRow dRow = namesDataTable.NewRow();
dRow["Name"] = "Name 1";
dRow["State"] = "xxx";
dRow["Date"] = "Y";
namesDataTable.Rows.Add(dRow);
dRow = namesDataTable.NewRow();
dRow["Name"] = "Name 2";
dRow["Date"] = "Y";
dRow["State"] = "xxx";
namesDataTable.Rows.Add(dRow);
dRow = namesDataTable.NewRow();
dRow["Name"] = "Name 3";
dRow["State"] = "xxx";
dRow["Date"] = "N";
namesDataTable.Rows.Add(dRow);
dRow = namesDataTable.NewRow();
dRow["Name"] = "Name 4";
dRow["State"] = "xxx";
dRow["Date"] ="N";
namesDataTable.Rows.Add(dRow);
dRow = namesDataTable.NewRow();
dRow["Name"] = "Name 5";
dRow["State"] = "xxx";
dRow["Date"] = "Y";
namesDataTable.Rows.Add(dRow);
namesDataTable.AcceptChanges();
}
private void AddGridStyle()
{
DataGridTableStyle myGridStyle = new DataGridTableStyle();
myGridStyle.MappingName = "NamesTable";
nameColumnStyle =
new DataGridTextBoxColumn();
nameColumnStyle.MappingName = "Name";
nameColumnStyle.HeaderText = "Name";
myGridStyle.GridColumnStyles.Add(nameColumnStyle);
XUIControls.DataGridComboBoxColumnStyle cmbStyle = new XUIControls.DataGridComboBoxColumnStyle();
cmbStyle.MappingName = "State";
cmbStyle.HeaderText = "State";
cmbStyle.Width = 100;
cmbStyle.AddItem("xxx");
cmbStyle.AddItem("1111");
myGridStyle.GridColumnStyles.Add(cmbStyle);
chkStyle = new XUIControls.DataGridCheckBoxColumnStyle();
chkStyle.MappingName = "Date";
chkStyle.HeaderText = "Date";
cmbStyle.Width = 100;
myGridStyle.GridColumnStyles.Add(chkStyle);
this.dataGrid1.TableStyles.Add(myGridStyle);
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(nameColumnStyle.TextBox.Text);
//if (chkStyle.)
/// MessageBox.Show("GDFG");
// else
// MessageBox.Show("hhh");
}
}
}
the form1.desiner.cs :
namespace NewDataGrid
{
partial class Form1
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.dataGrid1 = new System.Windows.Forms.DataGrid();//手工添加
this.button1 = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).BeginInit();//手工添加
this.SuspendLayout();
//
// dataGrid1
//
this.dataGrid1.CaptionText = "adsfsadfsadf";
this.dataGrid1.DataMember = "";
this.dataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText;
this.dataGrid1.Location = new System.Drawing.Point(12, 12);
this.dataGrid1.Name = "dataGrid1";
this.dataGrid1.Size = new System.Drawing.Size(407, 260);
this.dataGrid1.TabIndex = 1;// 这段手工添加
//
// button1
//
this.button1.Location = new System.Drawing.Point(179, 298);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 2;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(629, 461);
this.Controls.Add(this.button1);
this.Controls.Add(this.dataGrid1);//手工添加 如果你要增加到别的容器就用其代替this
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).EndInit();//手工增加
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button button1;
}
}
4.add codes and compile it
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////source codes--------------------------------------------------------------------------