} public delegate void DataGridCellButtonClickEventHandler(object sender, DataGridCellButtonClickEventArgs e); public class DataGridCellButtonClickEventArgs : EventArgs { private int _row; private int _col; public DataGridCellButtonClickEventArgs(int row, int col) { _row = row; _col = col; } public int RowIndex {get{return _row;}} public int ColIndex {get{return _col;}} }
————————————————————————————————C#中为DataGrid添加下拉列表框 WinForm 在 System.Windows.Forms.DataGrid中切入使用ComboBox控件,主要包括三方面的内容。
1. 在DataGrid中加入ComboBox列;
2. 把在DataGrid中的修改保存到对应的网格;
3. 设置DataGrid中网格的焦点。 下面是整个源代码,一些功能可以看注释。 using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data; namespace DataGridTest
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.DataGrid dgdFunctionArea;
private DataTable dtblFunctionalArea;
private System.Windows.Forms.Button buttonFocus;
private System.ComponentModel.Container components = null; public Form1()
{
InitializeComponent();
PopulateGrid();
} protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
} #region Windows 窗体设计器生成的代码 private void InitializeComponent()
{
this.dgdFunctionArea = new System.Windows.Forms.DataGrid();
this.buttonFocus = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.dgdFunctionArea)).BeginInit();
this.SuspendLayout();
//
// dgdFunctionArea
//
this.dgdFunctionArea.DataMember = "";
this.dgdFunctionArea.HeaderForeColor = System.Drawing.SystemColors.ControlText; this.dgdFunctionArea.Location = new System.Drawing.Point(4, 8);
this.dgdFunctionArea.Name = "dgdFunctionArea";
this.dgdFunctionArea.Size = new System.Drawing.Size(316, 168);
this.dgdFunctionArea.TabIndex = 0;
//
// buttonFocus
//
this.buttonFocus.Location = new System.Drawing.Point(232, 188);
this.buttonFocus.Name = "buttonFocus";
this.buttonFocus.Size = new System.Drawing.Size(84, 23);
this.buttonFocus.TabIndex = 1;
this.buttonFocus.Text = "获取焦点";
this.buttonFocus.Click += new System.EventHandler(this.buttonFocus_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(332, 217);
this.Controls.Add(this.buttonFocus);
this.Controls.Add(this.dgdFunctionArea);
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.dgdFunctionArea)).EndInit();
this.ResumeLayout(false); }
#endregion
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
//初始化DataGrid
private void PopulateGrid()
{
//创建一个DataTable对象,包括四列,前三列为String,最后一列为Boolean。
dtblFunctionalArea = new DataTable ("FunctionArea");
string[] arrstrFunctionalArea = new string [3]{"Functional Area","Min","Max"};
DataColumn dtCol = null;
//创建String列
for(int i=0; i< 3;i++)
{
dtCol = new DataColumn(arrstrFunctionalArea[i]);
dtCol.DataType = Type.GetType("System.String");
dtCol.DefaultValue = "";
dtblFunctionalArea.Columns.Add(dtCol);
} //创建Boolean列,用CheckedBox来显示。
DataColumn dtcCheck = new DataColumn("IsMandatory");
dtcCheck.DataType = System.Type.GetType("System.Boolean");
dtcCheck.DefaultValue = false;
dtblFunctionalArea.Columns.Add(dtcCheck); //把表绑定到DataGrid
dgdFunctionArea.DataSource = dtblFunctionalArea; //为DataGrid加载DataGridTableStyle样式
if(!dgdFunctionArea.TableStyles.Contains("FunctionArea"))
{
DataGridTableStyle dgdtblStyle = new DataGridTableStyle();
dgdtblStyle.MappingName = dtblFunctionalArea.TableName;
dgdFunctionArea.TableStyles.Add(dgdtblStyle);
dgdtblStyle.RowHeadersVisible = false;
dgdtblStyle.HeaderBackColor = Color.LightSteelBlue;
dgdtblStyle.AllowSorting = false;
dgdtblStyle.HeaderBackColor = Color.FromArgb(8,36,107);
dgdtblStyle.RowHeadersVisible = false;
dgdtblStyle.HeaderForeColor = Color.White;
dgdtblStyle.HeaderFont = new System.Drawing.Font("Microsoft Sans Serif", 9F,
System.Drawing.FontStyle.Bold,
System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
dgdtblStyle.GridLineColor = Color.DarkGray;
dgdtblStyle.PreferredRowHeight = 22;
dgdFunctionArea.BackgroundColor = Color.White; //设置列的宽度
GridColumnStylesCollection colStyle = dgdFunctionArea.TableStyles[0].GridColumnStyles;
colStyle[0].Width = 100;
colStyle[1].Width = 50;
colStyle[2].Width = 50;
colStyle[3].Width = 80;
} DataGridTextBoxColumn dgtb = (DataGridTextBoxColumn)dgdFunctionArea.TableStyles[0].GridColumnStyles[0]; ComboBox cmbFunctionArea = new ComboBox();
cmbFunctionArea.Items.AddRange(new object[]{"选项一","选项二","选项三"});
cmbFunctionArea.Cursor = Cursors.Arrow;
cmbFunctionArea.DropDownStyle= ComboBoxStyle.DropDownList;
cmbFunctionArea.Dock = DockStyle.Fill; //在选定项发生更改并且提交了该更改后发生 cmbFunctionArea.SelectionChangeCommitted += new EventHandler(cmbFunctionArea_SelectionChangeCommitted); //把ComboBox添加到DataGridTableStyle的第一列 dgtb.TextBox.Controls.Add(cmbFunctionArea); } //设置焦点模拟 private void GetFocus(int row,int col)
{
//先把焦点移动到DataGrid
this.dgdFunctionArea.Focus();
//把焦点移动到DataGridCell
DataGridCell dgc = new DataGridCell(row,col);
this.dgdFunctionArea.CurrentCell = dgc;
DataGridTextBoxColumn dgtb = (DataGridTextBoxColumn)dgdFunctionArea.TableStyles[0].GridColumnStyles[col]; //设置焦点 dgtb.TextBox.Focus();
} //把Combobox上修改的数据提交到当前的网格 private void cmbFunctionArea_SelectionChangeCommitted(object sender, EventArgs e)
{
this.dgdFunctionArea[this.dgdFunctionArea.CurrentCell] = ((ComboBox)sender).SelectedItem.ToString(); } //设置新的焦点 private void buttonFocus_Click(object sender, System.EventArgs e)
{
//焦点模拟,这里设置第三行第一列
GetFocus(2,0);
}
} } 这里是通过DataGridTextBoxColumn.TextBox.Controls.Add方法实现在列中添加ComboBox控件;对于数据的保存是使用ComboBox.SelectionChangeCommitted事件来完成;设置焦点是通过DataGridTextBoxColumn.TextBox.Focus方法来实现。另外通过这个方法也可以添加DateTimePicker等类似的控件。
但是Button和ComboBox不一样。。
public class DataGridButtonColumn : DataGridTextBoxColumn
{
public event DataGridCellButtonClickEventHandler CellButtonClicked; private Bitmap _button;
private Bitmap _buttonPressed;
private int _columnNum;
private int _pressedRow; public DataGridButtonColumn(int colNum)
{
_columnNum = colNum;
_pressedRow = -1; //you will need to change the Assembly name in GetManifestResourceStream()
try
{
char[] c={','};
System.IO.Stream strm = this.GetType().Assembly.GetManifestResourceStream(this.GetType().Assembly.ToString().Split(c,10)[0]+".button.bmp");
_button = new Bitmap(strm);
strm = this.GetType().Assembly.GetManifestResourceStream(this.GetType().Assembly.ToString().Split(c,10)[0]+".buttonpressed.bmp");
_buttonPressed = new Bitmap(strm);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
} } protected override void Edit(System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible)
{
// dont call the baseclass so no editing done...
// base.Edit(source, rowNum, bounds, readOnly, instantText, cellIsVisible);
} private void DrawButton(Graphics g, Bitmap bm, Rectangle bounds, int row)
{ DataGrid dg = this.DataGridTableStyle.DataGrid;
string s = dg[row, this._columnNum].ToString(); SizeF sz = g.MeasureString(s, dg.Font, bounds.Width - 4, StringFormat.GenericTypographic); int x = bounds.Left + Math.Max(0, (bounds.Width - (int)sz.Width)/2);
g.DrawImage(bm, bounds, 0, 0, bm.Width, bm.Height,GraphicsUnit.Pixel);
if(sz.Height < bounds.Height)
{
int y = bounds.Top + (bounds.Height - (int) sz.Height) / 2;
if(_buttonPressed == bm)
{
x++;
} g.DrawString(s, dg.Font, new SolidBrush(dg.ForeColor), x, y);
} } public void HandleMouseUp(object sender, MouseEventArgs e)
{
DataGrid dg = this.DataGridTableStyle.DataGrid;
DataGrid.HitTestInfo hti = dg.HitTest(new Point(e.X, e.Y));
bool isClickInCell = (hti.Column == this._columnNum
&& hti.Row > -1); _pressedRow = -1; Rectangle rect = new Rectangle(0,0,0,0); if(isClickInCell)
{
rect = dg.GetCellBounds(hti.Row, hti.Column);
isClickInCell = (e.X > rect.Right - this._button.Width);
}
if(isClickInCell)
{
Graphics g = Graphics.FromHwnd(dg.Handle);
// g.DrawImage(this._button, rect.Right - this._button.Width, rect.Y);
DrawButton(g, this._button, rect, hti.Row);
g.Dispose();
if(CellButtonClicked != null)
CellButtonClicked(this, new DataGridCellButtonClickEventArgs(hti.Row, hti.Column));
}
} public void HandleMouseDown(object sender, MouseEventArgs e)
{
DataGrid dg = this.DataGridTableStyle.DataGrid;
DataGrid.HitTestInfo hti = dg.HitTest(new Point(e.X, e.Y));
bool isClickInCell = (hti.Column == this._columnNum
&& hti.Row > -1); Rectangle rect = new Rectangle(0,0,0,0);
if(isClickInCell)
{
rect = dg.GetCellBounds(hti.Row, hti.Column);
isClickInCell = (e.X > rect.Right - this._button.Width);
} if(isClickInCell)
{
//Console.WriteLine("HandleMouseDown " + hti.Row.ToString());
Graphics g = Graphics.FromHwnd(dg.Handle);
//g.DrawImage(this._buttonPressed, rect.Right - this._buttonPressed.Width, rect.Y);
DrawButton(g, _buttonPressed, rect, hti.Row);
g.Dispose();
_pressedRow = hti.Row;
}
} protected override void Paint(System.Drawing.Graphics g, System.Drawing.Rectangle bounds, System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Brush backBrush, System.Drawing.Brush foreBrush, bool alignToRight)
{
//base.Paint(g, bounds, source, rowNum, backBrush, foreBrush, alignToRight);
DataGrid parent = this.DataGridTableStyle.DataGrid;
bool current = parent.IsSelected(rowNum) ||
( parent.CurrentRowIndex == rowNum &&
parent.CurrentCell.ColumnNumber == this._columnNum);
//draw the button
Bitmap bm = _pressedRow == rowNum ? this._buttonPressed : this._button;
this.DrawButton(g, bm, bounds, rowNum);
//font.Dispose();
}
} public delegate void DataGridCellButtonClickEventHandler(object sender, DataGridCellButtonClickEventArgs e); public class DataGridCellButtonClickEventArgs : EventArgs
{
private int _row;
private int _col; public DataGridCellButtonClickEventArgs(int row, int col)
{
_row = row;
_col = col;
} public int RowIndex {get{return _row;}}
public int ColIndex {get{return _col;}}
}