//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;
}
}