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