//DataGridView扩展类
//WDataGridView控件
public class WDataGridViewColumn_EditDelete : DataGridViewColumn { /// <summary> /// 对象名称:DataGridView操作按钮列(修改、删除) /// 对象说明:通过本类可以实现,在DataGridView控件中,显示一个分别包含修改和删除按钮的列。 /// </summary> public WDataGridViewColumn_EditDelete() { this.CellTemplate = new WDataGridViewCell_EditDelete(); this.HeaderText = "Operate"; } } /// <summary> /// DataGridView操作按钮单元格,继承自DataGridViewButtonCell类。 /// </summary> public class WDataGridViewCell_EditDelete : DataGridViewButtonCell { private Color m_clBrush = Color.White; private Color m_ModiclBrush = Color.FromArgb(47, 186, 0);//修改字体颜色 private Color m_DelclBrush = Color.Red;//删除字体颜色 private bool mouseOnModifyButton = false; // 鼠标是否移动到修改按钮上 private bool mouseOnDeleteButton = false; // 鼠标是否移动到删除按钮上 private static string strModify = "修改"; // 修改按钮背景图片 private static string strDelete = "删除"; // 删除按钮背景图片 private static Pen penModify = new Pen(Color.FromArgb(135, 163, 193)); // 修改按钮边框颜色 private static Pen penDelete = new Pen(Color.FromArgb(162, 144, 77)); // 删除按钮边框颜色 private static int nowColIndex = 0; // 当前列序号 private static int nowRowIndex = 0; // 当前行序号 /// <summary> /// 对单元格的重绘事件进行的方法重写。 /// </summary> protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) { base.PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle); cellBounds = PrivatePaint(graphics, cellBounds, rowIndex, cellStyle, true); } /// <summary> /// 私有的单元格重绘方法,根据鼠标是否移动到按钮上,对按钮的不同背景和边框进行绘制。 /// </summary> private Rectangle PrivatePaint(Graphics graphics, Rectangle cellBounds, int rowIndex, DataGridViewCellStyle cellStyle, bool clearBackground) { if (clearBackground) // 是否需要重绘单元格的背景颜色 { Brush brushCellBack; if (this.DataGridView.Rows[rowIndex].Selected) { brushCellBack = new SolidBrush(cellStyle.SelectionBackColor); } else { brushCellBack = new SolidBrush(cellStyle.BackColor); } graphics.FillRectangle(brushCellBack, cellBounds.X, cellBounds.Y, cellBounds.Width, cellBounds.Height); } int width = 16;//图片宽度 int height = 16;//图片高度 int AllWidth = 32;//图片总宽度 int Wdistance = (cellBounds.Width - AllWidth) / 3; //图片宽度的间距 int Hdistance = (cellBounds.Height - height) / 2; //图片高度间距 Rectangle recModify = new Rectangle(cellBounds.Location.X + 1, cellBounds.Y + 1, (cellBounds.Width - 3) / 2, cellBounds.Height - 2); Rectangle recDelete = new Rectangle(recModify.Right + 1, cellBounds.Y + 1, (cellBounds.Width - 3) / 2, cellBounds.Height - 2); Brush brushCellFore = new SolidBrush(m_clBrush); if (this.DataGridView.Rows[rowIndex].Selected) { brushCellFore = new SolidBrush(cellStyle.SelectionForeColor); } StringFormat sf = new StringFormat(); //sf.Trimming = StringTrimming.EllipsisCharacter; sf.LineAlignment = StringAlignment.Center; sf.Alignment = StringAlignment.Far; sf.FormatFlags = StringFormatFlags.NoWrap; string szFont = "微软雅黑"; // 修改按钮 graphics.DrawString(strModify, new Font(szFont, 9), new SolidBrush(m_ModiclBrush), recModify, sf); sf.Alignment = StringAlignment.Near; graphics.DrawString(strDelete, new Font(szFont, 9), new SolidBrush(m_DelclBrush), recDelete, sf); brushCellFore.Dispose(); return cellBounds; } /// <summary> /// 鼠标移动到单元格内时的事件处理,通过坐标判断鼠标是否移动到了修改或删除按钮上,并调用私有的重绘方法进行重绘。 /// </summary> protected override void OnMouseMove(DataGridViewCellMouseEventArgs e) { if (base.DataGridView == null) return; nowColIndex = e.ColumnIndex; nowRowIndex = e.RowIndex; if (nowColIndex == -1 || nowRowIndex == -1) return; Rectangle cellBounds = DataGridView[e.ColumnIndex, e.RowIndex].ContentBounds; Rectangle recModify = new Rectangle(cellBounds.Location.X + 1, cellBounds.Y + 1, (cellBounds.Width - 3) / 2, cellBounds.Height - 2); Rectangle recDelete = new Rectangle(recModify.Right + 1, cellBounds.Y + 1, (cellBounds.Width - 3) / 2, cellBounds.Height - 2); if (IsInRect(e.X, e.Y, recModify)) // 鼠标移动到修改按钮上 { if (!mouseOnModifyButton) { mouseOnModifyButton = true; DataGridView.Cursor = Cursors.Hand; } } else { if (mouseOnModifyButton) { mouseOnModifyButton = false; DataGridView.Cursor = Cursors.Default; } } if (IsInRect(e.X, e.Y, recDelete)) // 鼠标移动到删除按钮上 { if (!mouseOnDeleteButton) { mouseOnDeleteButton = true; DataGridView.Cursor = Cursors.Hand; } } else { if (mouseOnDeleteButton) { mouseOnDeleteButton = false; DataGridView.Cursor = Cursors.Default; } } } /// <summary> /// 鼠标从单元格内移出时的事件处理,调用私有的重绘方法进行重绘。 /// </summary> protected override void OnMouseLeave(int rowIndex) { if (mouseOnModifyButton != false || mouseOnDeleteButton != false) { mouseOnModifyButton = false; mouseOnDeleteButton = false; DataGridView.Cursor = Cursors.Default; } } /// <summary> /// 判断用户是否单击了修改按钮,DataGridView发生CellMouseClick事件时, /// 因本单元格中有两个按钮,本方法通过坐标判断用户是否单击了修改按钮。 /// </summary> public static bool IsModifyButtonClick(object sender, DataGridViewCellMouseEventArgs e) { if (e.RowIndex < 0 || e.ColumnIndex < 0) return false; if (sender is DataGridView) { DataGridView DgvGrid = (DataGridView)sender; if (DgvGrid.Columns[e.ColumnIndex] is WDataGridViewColumn_EditDelete) { Rectangle cellBounds = DgvGrid[e.ColumnIndex, e.RowIndex].ContentBounds; Rectangle recModify = new Rectangle(cellBounds.Location.X + 1, cellBounds.Location.Y + 1, (cellBounds.Width - 3) / 2, cellBounds.Height - 2); if (IsInRect(e.X, e.Y, recModify)) return true; } } return false; } /// <summary> /// 判断用户是否单击了删除按钮,DataGridView发生CellMouseClick事件时, /// 因本单元格中有两个按钮,本方法通过坐标判断用户是否单击了删除按钮。 /// </summary> public static bool IsDeleteButtonClick(object sender, DataGridViewCellMouseEventArgs e) { if (e.RowIndex < 0 || e.ColumnIndex < 0) return false; if (sender is DataGridView) { DataGridView DgvGrid = (DataGridView)sender; if (DgvGrid.Columns[e.ColumnIndex] is WDataGridViewColumn_EditDelete) { Rectangle cellBounds = DgvGrid[e.ColumnIndex, e.RowIndex].ContentBounds; Rectangle recDelete = new Rectangle(cellBounds.Location.X + (cellBounds.Width - 3) / 2 + 2, cellBounds.Location.Y + 1, (cellBounds.Width - 3) / 2, cellBounds.Height - 2); if (IsInRect(e.X, e.Y, recDelete)) return true; } } return false; } /// <summary> /// 判断鼠标坐标是否在指定的区域内。 /// </summary> private static bool IsInRect(int x, int y, Rectangle area) { if (x > area.Left && x < area.Right && y > area.Top && y < area.Bottom) return true; return false; } }