winForm自定义控件攻略之一
——winForm中为DataGrid增加单元格响应事件
51长假已经开始了,很多人已经上路或者准备上路——外出旅游了吧,小生祝大家玩得开心,回头可以贴些照片来弊站,借你们的余热暖暖,不至于让这里太冷。
想必另一些朋友已经安排加班了,远游是不行了,不过值得开心的是:银子没少赚吧!
记得我们的网站是www.pshf.cn,有你同行,我的世界更精彩。
好了,我们言归正传,开始我们的WinForm自定义控件了解,今天给大家切磋一下怎样为DataGrid增加单元格响应事件。
我们知道,DataGrid在可编辑状态下双击Cell时我们无从捕捉该双击,原因是焦点落到了Cell里了,而DataGrid没有提供Cell的双击事件。下面我们自己动手为DataGrid增加单击Cell、双击Cell、光标进入Cell事件,如果你愿意,你可以为DataGrid的Cell增加所有TextBox所拥有的事件,因为你可以把DataGrid中的Cell当成一个个的TextBox看。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms;
namespace MyControls { public partial class MyDataGrid : DataGrid { public MyDataGrid() { InitializeComponent(); }
protected override void OnPaint(PaintEventArgs pe) { // TODO: 在此处添加自定义绘制代码
// 调用基类 OnPaint base.OnPaint(pe); }
//如下是我们需要添加的代码
//当前列索引 private int _CurrentCellColumnIndex = -1; /// <summary> /// 提供只读列索引属性 /// 当响应我们的OnCell系列的事件时,该值指示我们正在操作的列索引 /// </summary> public int CurrentCellColumnIndex { get { return _CurrentCellColumnIndex; } } //记录鼠标单击的位置 System.Windows.Forms.DataGrid.HitTestInfo HTI;
/// <summary> /// 重写OnMouseDown,记录鼠标按下时的位置信息 /// </summary> /// <param name="e"></param> protected override void OnMouseDown(MouseEventArgs e) { HTI = base.HitTest(e.X, e.Y); base.OnMouseDown(e); }
/// <summary> /// 我们新定义数据邦定方法 /// </summary> /// <param name="dataSource"></param> /// <param name="dataMember"></param> public new void SetDataBinding(object dataSource, string dataMember) { base.DataSource = null; base.SetDataBinding(dataSource, dataMember); //为DataGrid增加样式风格(DataGrid的外观显示都靠它) DataGridTableStyle CurrTableStyle = new DataGridTableStyle(); this.TableStyles.Clear(); this.TableStyles.Add(CurrTableStyle); //为Cell增加事件处理 SetTextBoxColmun(); }
/// <summary> /// 重写ProcessCmdKey,用于光标落在Cell中时,回车事件能够将焦点移到同行的下一Cell中 /// 如果不重写该方法,回车事件默认将光标落在下行同列的Cell中 /// </summary> /// <param name="msg"></param> /// <param name="keyData"></param> /// <returns></returns> protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { // int WM_KEYDOWN = 256; int WM_SYSKEYDOWN = 260; if ((msg.Msg == WM_KEYDOWN) || (msg.Msg == WM_SYSKEYDOWN)) { switch (keyData) { case Keys.Down: case Keys.Up: //case Keys.Control+Keys.M: //case Keys.Alt+Keys.Z: return true; case Keys.Enter: SendKeys.Send("{Tab}"); return true; } } return base.ProcessCmdKey(ref msg, keyData); }
//如下定义我们的事件,该事件可显示在设计器中,另见图片 [Category("pshf.cn")] [Description("当双击Cell时发生")] public event EventHandler OnCellDoubleClick; [Category("pshf.cn")] [Description("当单击Cell时发生")] public event EventHandler OnCellClick; [Category("pshf.cn")] [Description("当离开Cell时发生")] public event EventHandler OnCellLeave; /// <summary> /// 设置列为文本框 /// </summary> private void SetTextBoxColmun() {
foreach (DataGridColumnStyle dgcs in this.TableStyles[0].GridColumnStyles) { //将网格中的null显示为空字符 dgcs.NullText = string.Empty; //可以把我们的Cell看成一个个的TextBox DataGridTextBoxColumn dgtext1 = (DataGridTextBoxColumn)dgcs; dgtext1.TextBox.DoubleClick += new EventHandler(TextBox_DoubleClick); dgtext1.TextBox.Leave += new EventHandler(TextBox_Leave); dgtext1.TextBox.Click += new EventHandler(TextBox_Click); dgtext1.TextBox.KeyDown += new KeyEventHandler(TextBox_KeyDown); dgtext1.TextBox.MouseEnter += new EventHandler(TextBox_MouseEnter); } } /// <summary> /// 当光标进入Cell时触发 /// 为防止鼠标右键->粘贴输入单引号,我们要对剪贴板数据进行处理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void TextBox_MouseEnter(object sender, EventArgs e) { //处理剪切板上的特殊字符 IDataObject data = Clipboard.GetDataObject(); if (data.GetDataPresent(DataFormats.Text)) Clipboard.SetDataObject(data.GetData(DataFormats.Text).ToString().Replace("'", "")); }
/// <summary> /// 当按下键盘键时发生 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void TextBox_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter)//如果回车,则跳到下一单元格,而不是下一行 SendKeys.Send("{Tab}"); else if (e.KeyCode == Keys.Oem7)//屏蔽单引号 e.Handled = true; } /// <summary> /// 当光标离开时发生 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void TextBox_Leave(object sender, EventArgs e) { if (OnCellLeave != null && sender.GetType().Name == "DataGridTextBox") { if (((DataGridTextBox)sender).Text.Length == 0) return; this._CurrentCellColumnIndex = HTI.Column; OnCellLeave(sender, e); } } /// <summary> /// Cell单击 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void TextBox_Click(object sender, EventArgs e) { if (OnCellClick != null && sender.GetType().Name == "DataGridTextBox") { this._CurrentCellColumnIndex = HTI.Column; OnCellClick(sender, e); } } /// <summary> /// Cell双击 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void TextBox_DoubleClick(object sender, EventArgs e) { if (OnCellDoubleClick != null && sender.GetType().Name == "DataGridTextBox") { this._CurrentCellColumnIndex = HTI.Column; OnCellDoubleClick(sender, e); KeyEventArgs ke = new KeyEventArgs(Keys.Enter); TextBox_KeyDown(sender, ke); } } } }
|