Hi,
I'm having problems with the following code, my mouseenter seems to force a datagridviewcell repaint, however the mouseleave event does not. leaving my two vertical lines on the button instead of repainting without the lines
Can anyone plz help
#Region " DataGridViewDropDownButtonColumn"
<DesignerSerializer(GetType(DataGridViewDropDownButtonSerializer), GetType(CodeDomSerializer))> _
Public Class DataGridViewDropDownButtonColumn
Inherits DataGridViewButtonColumn
#Region " Variables"
Private enabledValue As Boolean = False
Private m_Items As ToolStripMenuItem()
#End Region
#Region " Events"
Public Event Items_Clicked(ByVal sender As Object, ByVal e As DataGridViewDropDownButtonEventArgs)
#End Region
#Region " Properties"
<Browsable(False)> _
Public Property Enabled() As Boolean
Get
Return enabledValue
End Get
Set(ByVal value As Boolean)
enabledValue = value
End Set
End Property
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
Public Property Items() As ToolStripMenuItem()
Get
Return m_Items
End Get
Set(ByVal value As ToolStripMenuItem())
Array.Resize(m_Items, value.Length)
Array.Copy(value, m_Items, value.Length)
For Each tsmi As ToolStripMenuItem In m_Items
AddHandler tsmi.Click, AddressOf DropDown_Clicked
Next
End Set
End Property
#End Region
#Region " Constructor"
Public Sub New()
Me.CellTemplate = New DataGridViewDropDownButtonCell()
enabledValue = False
End Sub
#End Region
#Region " Methods"
Public Overrides Function Clone() As Object
Dim Column As DataGridViewDropDownButtonColumn = CType(MyBase.Clone(), DataGridViewDropDownButtonColumn)
Column.m_Items = m_Items
Column.enabledValue = enabledValue
Return Column
End Function
Public Sub DropDown_Clicked(ByVal sender As Object, ByVal e As System.EventArgs)
'me.DataGridView.CurrentCell.RowIndex
RaiseEvent Items_Clicked(Me, New DataGridViewDropDownButtonEventArgs(sender _
, DataGridView.CurrentCell.ColumnIndex _
, DataGridView.CurrentCell.RowIndex))
End Sub
#End Region
End Class
#End Region
#Region " DataGridViewDropDownButtonCell"
Public Class DataGridViewDropDownButtonCell
Inherits DataGridViewButtonCell
#Region " Variables"
Private Shared m_borderSize As Integer = SystemInformation.Border3DSize.Width * 2
Private m_buttonState As System.Windows.Forms.VisualStyles.PushButtonState = PushButtonState.Normal
Private m_pushButtonWidth As Integer = 20
Dim m_contextmenu As ContextMenuStrip
Dim m_drawSplitLine As Boolean = False
#End Region
#Region " Properties"
Private Property ButtonState() As System.Windows.Forms.VisualStyles.PushButtonState
Get
Return m_buttonState
End Get
Set(ByVal value As System.Windows.Forms.VisualStyles.PushButtonState)
If Not m_buttonState.Equals(value) Then
m_buttonState = value
Me.DataGridView.InvalidateCell(Me.ColumnIndex, Me.RowIndex)
End If
End Set
End Property
#End Region
#Region " Constructor"
Public Sub New()
m_contextmenu = New ContextMenuStrip()
End Sub
#End Region
#Region " Methods"
' Override the Clone method so that the Enabled property is copied.
Public Overrides Function Clone() As Object
Dim Cell As DataGridViewDropDownButtonCell = _
CType(MyBase.Clone(), DataGridViewDropDownButtonCell)
Cell.m_buttonState = m_buttonState
Cell.m_pushButtonWidth = m_pushButtonWidth
Cell.m_contextmenu = m_contextmenu
Cell.m_drawSplitLine = m_drawSplitLine
Return Cell
End Function
Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs)
Dim col As DataGridViewDropDownButtonColumn = CType(Me.OwningColumn, DataGridViewDropDownButtonColumn)
If col.Items IsNot Nothing Then
Dim dropDownButton As Rectangle = New Rectangle(ContentBounds.Right - m_pushButtonWidth - 1, m_borderSize, m_pushButtonWidth, ContentBounds.Height + m_pushButtonWidth * 2)
If dropDownButton.Contains(e.Location) Then
If col.Enabled = False Then
m_contextmenu.Items.AddRange(CType(Me.OwningColumn, DataGridViewDropDownButtonColumn).Items)
Dim d As Rectangle = Me.DataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, False)
m_contextmenu.Show(Me.DataGridView.PointToScreen(New Point(d.X + d.Width, d.Bottom)), ToolStripDropDownDirection.Left)
col.Enabled = True
Else
m_contextmenu.Hide()
col.Enabled = False
End If
Else
ButtonState = PushButtonState.Pressed
DirectCast(Me.OwningColumn, DataGridViewDropDownButtonColumn).DropDown_Clicked(Nothing, Nothing)
End If
End If
End Sub
Protected Overrides Sub OnMouseEnter(ByVal rowIndex As Integer)
MyBase.OnMouseEnter(rowIndex)
ButtonState = PushButtonState.Hot
End Sub
Protected Overrides Sub OnMouseLeave(ByVal rowIndex As Integer)
MyBase.OnMouseLeave(rowIndex)
ButtonState = System.Windows.Forms.VisualStyles.PushButtonState.Normal
End Sub
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)
MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts)
' Draw the background of the cell, if specified.
If (paintParts And DataGridViewPaintParts.Background) = _
DataGridViewPaintParts.Background Then
Dim cellBackground As New SolidBrush(cellStyle.BackColor)
graphics.FillRectangle(cellBackground, cellBounds)
cellBackground.Dispose()
End If
' Draw the cell borders, if specified.
If (paintParts And DataGridViewPaintParts.Border) = _
DataGridViewPaintParts.Border Then
PaintBorder(graphics, clipBounds, cellBounds, cellStyle, _
advancedBorderStyle)
End If
' Calculate the area in which to draw the button.
Dim buttonArea As Rectangle = cellBounds
Dim buttonAdjustment As Rectangle = _
Me.BorderWidths(advancedBorderStyle)
buttonArea.X += buttonAdjustment.X
buttonArea.Y += buttonAdjustment.Y
buttonArea.Height -= buttonAdjustment.Height
buttonArea.Width -= buttonAdjustment.Width
' Draw the button.
ButtonRenderer.DrawButton(graphics, buttonArea, _
PushButtonState.Normal)
PaintArrow(graphics, cellBounds)
m_drawSplitLine = (ButtonState = System.Windows.Forms.VisualStyles.PushButtonState.Hot OrElse ButtonState = System.Windows.Forms.VisualStyles.PushButtonState.Pressed OrElse Not Application.RenderWithVisualStyles)
If m_drawSplitLine Then
' draw two lines at the edge of the dropdown button
graphics.DrawLine(SystemPens.ButtonShadow, buttonArea.Right - m_pushButtonWidth, buttonArea.Y + 3, buttonArea.Right - m_pushButtonWidth, buttonArea.Bottom - 3)
graphics.DrawLine(SystemPens.ButtonFace, buttonArea.Right - m_pushButtonWidth - 1, buttonArea.Y + 3, buttonArea.Right - m_pushButtonWidth - 1, buttonArea.Bottom - 3)
End If
If State <> System.Windows.Forms.VisualStyles.PushButtonState.Hot AndAlso (elementState And DataGridViewElementStates.Selected) <> 0 Then
ControlPaint.DrawFocusRectangle(graphics, cellBounds)
End If
End Sub
Private Sub PaintArrow(ByVal g As Graphics, ByVal dropDownRect As Rectangle)
Dim middle As New Point(dropDownRect.Right - ((m_pushButtonWidth + m_borderSize) / 2), dropDownRect.Top + (dropDownRect.Height / 2))
'if the width is odd - favor pushing it over one pixel right.
middle.X += (dropDownRect.Right Mod 2)
Dim arrow As Point() = New Point() {New Point(middle.X - 3, middle.Y - 1), New Point(middle.X + 4, middle.Y - 1), New Point(middle.X, middle.Y + 3)}
g.FillPolygon(SystemBrushes.ControlText, arrow)
End Sub
#End Region
End Class
#End Region