我在标签控件上有一个DGV
,它的父标签不是最初可见的标签(即TabPage2上的标签可见的TabPage2上的dgv)。
在表单加载时填充并分配网格数据源,在数据绑定中完成我添加新列并为其标题单元格点击分配事件处理程序,到目前为止一切正常。
但是,当我更改选项卡以使DGV
可见数据绑定完成第二次触发时,在此阶段事件处理程序已丢失,导致事件再次触发的原因是什么?
导致事件处理程序丢失的原因是什么?有办法解决这个问题吗?
由于
编辑:
原因似乎是列恢复为基础类型,即在DataBindingComplete中我添加了一个继承自DataGridViewTextBoxColumn的列DGVTextColumn,第二次DataBindingComplete触发列的类型为DataGridViewTextBoxColumn而不是继承类型DGVTextColumn哪有帮助?
重要的因素似乎是要绑定的列,采用空表单并向其添加制表符控件,在tabpage2中放置datagridview
,还原为tabpage1将底部的代码粘贴到表单代码中
Private Sub DataGridView1_DataBindingComplete(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewBindingCompleteEventArgs) Handles DataGridView1.DataBindingComplete
If Not DataGridView1.Columns.Contains("colBool") Then
Dim col As New DGVColumn
col.Name = "colBool"
col.DataPropertyName = "Checked" 'When this is included the checkbox appears unticked, however commenting this line out means that the checkbox appears ticked upon changing to TabPage2
col.Checked = True
DataGridView1.Columns.Add(col)
End If
End Sub
重现的代码:
Imports System.ComponentModel
Imports System.Windows.Forms.VisualStyles
Public Class Form1
Private list As BindingList(Of iPerson)
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
list = New BindingList(Of iPerson)
list.Add(New Person(0, "Steve", "Smith"))
list.Add(New Person(1, "Gomez", "Juan"))
list.Add(New Person(1, "Jones", "Paul"))
DataGridView1.DataSource = list
End Sub
Private Sub DataGridView1_DataBindingComplete(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewBindingCompleteEventArgs) Handles DataGridView1.DataBindingComplete
If Not DataGridView1.Columns.Contains("colBool") Then
Dim col As New DGVColumn
col.Name = "colBool"
col.DataPropertyName = "Checked"
col.Checked = True
DataGridView1.Columns.Add(col)
End If
End Sub
Private Interface iPerson
ReadOnly Property Forename() As String
ReadOnly Property Surname() As String
ReadOnly Property Checked() As Boolean
End Interface
Private Class Person
Implements iPerson
Private _ID As Integer
Private _Forename As String
Private _Surname As String
Private _checked As Boolean
Public Sub New(ByVal ID As Integer, ByVal Forename As String, ByVal Surname As String)
_ID = ID
_Forename = Forename
_Surname = Surname
_checked = False
End Sub
Public ReadOnly Property Forename() As String Implements iPerson.Forename
Get
Return _Forename
End Get
End Property
Public ReadOnly Property Surname() As String Implements iPerson.Surname
Get
Return _Surname
End Get
End Property
Public ReadOnly Property Checked() As Boolean Implements iPerson.Checked
Get
Return _checked
End Get
End Property
End Class
Private Class DGVHeaderCell
Inherits DataGridViewColumnHeaderCell
Private checkBoxLocation As Point
Private checkBoxSize As Size
Private _checked As Boolean = False
Private _cellLocation As New Point()
Public Event OnCheckBoxClicked()
Public Sub New()
End Sub
Protected Overrides Function GetPreferredSize(ByVal graphics As System.Drawing.Graphics, ByVal cellStyle As System.Windows.Forms.DataGridViewCellStyle, ByVal rowIndex As Integer, ByVal constraintSize As System.Drawing.Size) As System.Drawing.Size
Dim calcSize = MyBase.GetPreferredSize(graphics, cellStyle, rowIndex, constraintSize)
calcSize.Height += CheckBoxRenderer.GetGlyphSize(graphics, System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal).Height + 3
Return calcSize
End Function
Protected Overrides Sub Paint(ByVal graphics As System.Drawing.Graphics, ByVal clipBounds As System.Drawing.Rectangle, ByVal cellBounds As System.Drawing.Rectangle, ByVal rowIndex As Integer, ByVal dataGridViewElementState 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, dataGridViewElementState, "", "", errorText, cellStyle, advancedBorderStyle, paintParts)
Dim p As New Point()
Dim s As Size = CheckBoxRenderer.GetGlyphSize(graphics, System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal)
p.X = CInt(cellBounds.Location.X + (cellBounds.Width / 2) - (s.Width / 2))
p.Y = cellBounds.Location.Y + cellBounds.Height - s.Height - 3
Dim rect As Rectangle = cellBounds
rect.Height -= CheckBoxRenderer.GetGlyphSize(graphics, System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal).Height
Using txtBrush As New SolidBrush(cellStyle.ForeColor)
Dim format As New StringFormat
format.Alignment = StringAlignment.Center
format.LineAlignment = StringAlignment.Center
graphics.DrawString(formattedValue.ToString, cellStyle.Font, txtBrush, rect, format)
End Using
_cellLocation = cellBounds.Location
checkBoxLocation = p
checkBoxSize = s
Dim _cbState As CheckBoxState = System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal
If _checked Then
_cbState = System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal
End If
CheckBoxRenderer.DrawCheckBox(graphics, checkBoxLocation, _cbState)
End Sub
Protected Overrides Sub OnMouseClick(ByVal e As DataGridViewCellMouseEventArgs)
Dim p As New Point(e.X + _cellLocation.X, e.Y + _cellLocation.Y)
If p.X >= checkBoxLocation.X AndAlso p.X <= checkBoxLocation.X + checkBoxSize.Width AndAlso p.Y >= checkBoxLocation.Y AndAlso p.Y <= checkBoxLocation.Y + checkBoxSize.Height Then
_checked = Not _checked
RaiseEvent OnCheckBoxClicked()
Me.DataGridView.InvalidateCell(Me)
End If
MyBase.OnMouseClick(e)
End Sub
Public Property Checked() As Boolean
Get
Return _checked
End Get
Set(ByVal value As Boolean)
_checked = value
End Set
End Property
End Class
Friend Class DGVColumn
Inherits DataGridViewTextBoxColumn
Private _headerCell As DGVHeaderCell
Public Sub New()
_headerCell = New DGVHeaderCell()
AddHandler _headerCell.OnCheckBoxClicked, AddressOf THISHANDLER
Me.HeaderCell = _headerCell
Me.Width = 50
End Sub
Private Sub THISHANDLER()
MsgBox("Clicked")
End Sub
Public Property Checked() As Boolean
Get
Return _headerCell.Checked
End Get
Set(ByVal value As Boolean)
_headerCell.Checked = value
End Set
End Property
End Class
结束班
答案 0 :(得分:0)
覆盖HeaderCell和Column的克隆解决了问题
Public Overrides Function Clone() As Object
Dim Copy As DGVColumn = DirectCast(MyBase.Clone, DGVColumn)
Copy._headerCell = DirectCast(_headerCell.Clone, DataGridViewColumnHeaderCell)
Copy.HeaderCell = Copy._HeaderCell
Return Copy
End Function