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