使用DataGridView控件时需要每一行都有一个查看、修改、删除按钮,可以添加按钮列来实现,可是每一列只能有一个按钮,怎么看都不够美观,于是想能不能在单元格把按钮给画上去。
实例下载链接:https://download.csdn.net/download/zyjq52uys/12456524
效果图如下:
直接上代码:
DataGridViewEx:
Public Class DataGridViewEx
Inherits DataGridView
'''
''' 修改按钮点击事件
'''
'''
'''
Public Event CellButtonModifyClicked(ByVal sender As Object, ByVal e As EventArgsEx.DataGridViewClickEventArgsEx)
'''
''' 删除按钮点击事件
'''
'''
'''
Public Event CellButtonDeleteClicked(ByVal sender As Object, ByVal e As EventArgsEx.DataGridViewClickEventArgsEx)
#Region "按钮事件"
'''
''' 引发CellButtonModifyClicked事件
'''
'''
'''
'''
Friend Sub OnCellButtonModifyClicked(ByVal columnIndex As Integer, ByVal rowIndex As Integer, ByVal value As Object)
RaiseEvent CellButtonModifyClicked(Me, New EventArgsEx.DataGridViewClickEventArgsEx(columnIndex, rowIndex, value))
End Sub
'''
''' 引发CellButtonDeleteClicked事件
'''
'''
'''
'''
Friend Sub OnCellButtonDeleteClicked(ByVal columnIndex As Integer, ByVal rowIndex As Integer, ByVal value As Object)
RaiseEvent CellButtonDeleteClicked(Me, New EventArgsEx.DataGridViewClickEventArgsEx(columnIndex, rowIndex, value))
End Sub
#End Region
End Class
DataGridViewButtonColumnEx:
Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Windows.Forms
Imports System.Drawing
Imports System.ComponentModel
Imports System.Windows.Forms.VisualStyles
Public Class DataGridViewButtonColumnEx
Inherits DataGridViewColumn
Shared DefaultButtonSize As Size = New Size(35, 24)
Private _ButtonSize As Size = DefaultButtonSize
'''
''' 按钮大小模板Size
'''
'''
Public Property ButtonSize As Size
Get
Return _ButtonSize
End Get
Set(ByVal value As Size)
_ButtonSize = value
End Set
End Property
Shared ReadOnly DefaultButtonBack As Color = Color.Gainsboro
'''
''' 鼠标移到按钮时的背景色
'''
'''
Public Property ButtonBack As Color = DefaultButtonBack
Shared ReadOnly DefaultButtonTextDownColor As Color = Color.Red
'''
''' 按钮按下时文本色
'''
'''
Public Property ButtonTextDownColor As Color = DefaultButtonTextDownColor
Shared ReadOnly DefaultButtonTextFace As Color = Color.Blue
'''
''' 默认按钮文本色
'''
'''
Public Property ButtonTextFace As Color = DefaultButtonTextFace
Shared ReadOnly DefaultButtonSpacingWidth As Int32 = 3
Private _ButtonSpacingWidth As Int32 = DefaultButtonSpacingWidth
'''
''' 按钮间距
'''
'''
Public Property ButtonSpacingWidth As Int32
Get
Return _ButtonSpacingWidth
End Get
Set(value As Int32)
If value > 0 Then
_ButtonSpacingWidth = value
End If
End Set
End Property
'''
''' 修改按钮文本
'''
'''
Public Property ButtonModifyText As String = "修改"
'''
''' 删除按钮文本
'''
'''
Public Property ButtonDeleteText As String = "删除"
Public Overrides Function Clone() As Object
Dim column As DataGridViewButtonTwoColumnEx = CType(MyBase.Clone(), DataGridViewButtonTwoColumnEx)
column.ButtonModifyText = ButtonModifyText
column.ButtonDeleteText = ButtonDeleteText
Return column
End Function
Public Sub New()
MyBase.New()
Me.CellTemplate = New DataGridViewButtonTwoCellEx()
Me.HeaderText = "操作"
Me.MinimumWidth = DefaultButtonSize.Width * 2 + DefaultButtonSpacingWidth * 3
End Sub
End Class
DataGridViewButtonCellEx:
Imports System.Windows.Forms
Imports System.Drawing
Imports System.ComponentModel
Imports System.Windows.Forms.VisualStyles
Public Class DataGridViewButtonCellEx
Inherits DataGridViewButtonCell
'''
''' 按键类型枚举
'''
Public Enum ButtonType
'''
''' 修改按钮
'''
ButtonModify = 1
'''
''' 删除按钮
'''
ButtonDelete = 2
End Enum
'''
''' 按钮状态枚举
'''
Public Enum ButtonState
'''
''' 默认状态
'''
ButtonDefault = 1
'''
''' 热状态
'''
ButtonHot = 2
'''
''' 鼠标按下状态
'''
ButtonDown = 3
End Enum
Public ReadOnly Property OwningColumnEx As DataGridViewButtonTwoColumnEx
Get
Return TryCast(Me.OwningColumn, DataGridViewButtonTwoColumnEx)
End Get
End Property
Public ReadOnly Property DataGridViewEx As DataGridViewEx
Get
Return TryCast(Me.DataGridView, DataGridViewEx)
End Get
End Property
'修改按钮状态标志
Private m_ButtonModifyState As ButtonState = ButtonState.ButtonDefault
'删除按钮状态标志
Private m_ButtonDeleteState As ButtonState = ButtonState.ButtonDefault
Protected Overrides Sub Paint(ByVal graphics As Graphics,
ByVal clipBounds As Rectangle,
ByVal cellBounds As Rectangle,
ByVal rowIndex As Integer,
ByVal elementState As DataGridViewElementStates,
ByVal value As Object,
ByVal formattedValue As Object,
ByVal errorText As String,
ByVal cellStyle As DataGridViewCellStyle,
ByVal advancedBorderStyle As DataGridViewAdvancedBorderStyle,
ByVal paintParts As DataGridViewPaintParts)
'是否需要重绘单元格的背景颜色
'm_brushCellBack = If(Me.DataGridView.SelectedCells.Contains(Me), New SolidBrush(cellStyle.SelectionBackColor), New SolidBrush(cellStyle.BackColor))
'单元格背景色
Dim brushCellBack As Brush = New SolidBrush(cellStyle.BackColor)
graphics.FillRectangle(brushCellBack, cellBounds.X, cellBounds.Y, cellBounds.Width, cellBounds.Height)
'绘制Modify按钮
Me.InternalDrawButton(graphics, cellBounds, OwningColumnEx.ButtonModifyText, ButtonType.ButtonModify, m_ButtonModifyState)
'绘制Delete按钮
Me.InternalDrawButton(graphics, cellBounds, OwningColumnEx.ButtonDeleteText, ButtonType.ButtonDelete, m_ButtonDeleteState)
'填充单元格的边框
MyBase.PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle)
End Sub
'''
''' 绘制按钮
'''
'''
'''
''' 按钮类型枚举
''' 按钮状态枚举
Protected Sub InternalDrawButton(ByVal graphics As Graphics,
ByVal cellBounds As Rectangle,
ByVal buttonText As String,
ByVal buttonType As ButtonType,
ByVal buttonState As ButtonState)
' 当前按钮位置大小
Dim absBtnRegion As Rectangle = Rectangle.Empty
'按钮背景色画笔
Dim solidBrushButton As SolidBrush = New SolidBrush(OwningColumnEx.ButtonBack)
' 当前按钮绝对位置大小
Dim buttonRegion As Rectangle = RectangleCommon.GetSmallRectOfRectangle(cellBounds, OwningColumnEx.ButtonSize, OwningColumnEx.ButtonSpacingWidth, buttonType, absBtnRegion)
'单元格列宽太小则不绘制
If Not cellBounds.Contains(buttonRegion.X + buttonRegion.Width, buttonRegion.Y) Then Return
'绘制按钮
Select Case buttonState
Case ButtonState.ButtonHot
graphics.FillRectangle(solidBrushButton, buttonRegion)
TextRenderer.DrawText(graphics, buttonText, Me.DataGridView.Font, buttonRegion, OwningColumnEx.ButtonTextFace)
Case ButtonState.ButtonDown
graphics.FillRectangle(solidBrushButton, buttonRegion)
TextRenderer.DrawText(graphics, buttonText, Me.DataGridView.Font, buttonRegion, OwningColumnEx.ButtonTextDownColor)
Case Else
TextRenderer.DrawText(graphics, buttonText, Me.DataGridView.Font, buttonRegion, OwningColumnEx.ButtonTextFace)
End Select
End Sub
Protected Overrides Sub OnMouseMove(ByVal e As DataGridViewCellMouseEventArgs)
MyBase.OnMouseMove(e)
If IsInRegion(e.Location, ButtonType.ButtonModify, e.ColumnIndex, e.RowIndex) Then
m_ButtonModifyState = ButtonState.ButtonHot
m_ButtonDeleteState = ButtonState.ButtonDefault
Me.DataGridView.Cursor = Cursors.Hand
ElseIf IsInRegion(e.Location, ButtonType.ButtonDelete, e.ColumnIndex, e.RowIndex) Then
m_ButtonModifyState = ButtonState.ButtonDefault
m_ButtonDeleteState = ButtonState.ButtonHot
Me.DataGridView.Cursor = Cursors.Hand
Else
m_ButtonModifyState = ButtonState.ButtonDefault
m_ButtonDeleteState = ButtonState.ButtonDefault
Me.DataGridView.Cursor = Cursors.Default
End If
Me.DataGridView.InvalidateCell(Me)
End Sub
Protected Overrides Sub OnMouseLeave(ByVal rowIndex As Integer)
MyBase.OnMouseLeave(rowIndex)
m_ButtonModifyState = ButtonState.ButtonDefault
m_ButtonDeleteState = ButtonState.ButtonDefault
Me.DataGridView.Cursor = Cursors.Default
Me.DataGridView.InvalidateCell(Me)
End Sub
Protected Overrides Sub OnMouseDown(ByVal e As DataGridViewCellMouseEventArgs)
MyBase.OnMouseDown(e)
If IsInRegion(e.Location, ButtonType.ButtonModify, e.ColumnIndex, e.RowIndex) Then
m_ButtonModifyState = ButtonState.ButtonDown
m_ButtonDeleteState = ButtonState.ButtonDefault
Me.DataGridView.Cursor = Cursors.Hand
ElseIf IsInRegion(e.Location, ButtonType.ButtonDelete, e.ColumnIndex, e.RowIndex) Then
m_ButtonModifyState = ButtonState.ButtonDefault
m_ButtonDeleteState = ButtonState.ButtonDown
Me.DataGridView.Cursor = Cursors.Hand
Else
m_ButtonModifyState = ButtonState.ButtonDefault
m_ButtonDeleteState = ButtonState.ButtonDefault
Me.DataGridView.Cursor = Cursors.Default
End If
Me.DataGridView.InvalidateCell(Me)
End Sub
Protected Overrides Sub OnMouseClick(ByVal e As DataGridViewCellMouseEventArgs)
MyBase.OnMouseClick(e)
If e.Button = MouseButtons.Left Then
If Me.DataGridViewEx IsNot Nothing Then
If IsInRegion(e.Location, ButtonType.ButtonModify, e.ColumnIndex, e.RowIndex) Then
Me.DataGridViewEx.OnCellButtonModifyClicked(e.ColumnIndex, e.RowIndex, Me.Value)
ElseIf IsInRegion(e.Location, ButtonType.ButtonDelete, e.ColumnIndex, e.RowIndex) Then
Me.DataGridViewEx.OnCellButtonDeleteClicked(e.ColumnIndex, e.RowIndex, Me.Value)
End If
End If
End If
End Sub
Protected Function IsInRegion(ByVal p As Point, ByVal buttonType As ButtonType, ByVal columnIndex As Integer, ByVal rowIndex As Integer) As Boolean
Dim cellBounds As Rectangle = DataGridView(columnIndex, rowIndex).ContentBounds
Dim absBtnRegion As Rectangle = Rectangle.Empty
RectangleCommon.GetSmallRectOfRectangle(cellBounds, OwningColumnEx.ButtonSize, OwningColumnEx.ButtonSpacingWidth, buttonType, absBtnRegion)
Return absBtnRegion.Contains(p)
End Function
End Class
获取按钮位置:
Public Class RectangleCommon
'''
''' 获取在大的Rectangle中的小矩形
'''
''' 单元格Rectangle
''' 绘制按钮的Size
''' 两按钮的间距
''' 按钮类型
''' 输出的按钮相对单元格的Rectangle
''' 返回按钮的绝对Rectangle
Public Shared Function GetSmallRectOfRectangle(ByVal rectangle As Rectangle, ByVal smallSize As Size, ByVal SpacingWidth As Int32, ByVal buttonType As Int32, ByRef absRectangle As Rectangle) As Rectangle
Dim rect As Rectangle = New Rectangle()
absRectangle = New Rectangle()
absRectangle.Size = smallSize
absRectangle.X = SpacingWidth + (SpacingWidth + smallSize.Width) * (buttonType - 1)
absRectangle.Y = (rectangle.Height - smallSize.Height) \ 2
rect.Size = smallSize
rect.X = absRectangle.X + rectangle.X
rect.Y = absRectangle.Y + rectangle.Y
Return rect
End Function
End Class
单击链接单元格内容事件数据:
Public Class DataGridViewClickEventArgsEx
Inherits EventArgs
Public Property ColumnIndex As Integer
Public Property RowIndex As Integer
Public Property Value As Object
Public Sub New(ByVal columnIndex As Integer, ByVal rowIndex As Integer, ByVal value As Object)
Me.ColumnIndex = columnIndex
Me.RowIndex = rowIndex
Me.Value = value
End Sub
End Class