DGV DataBindingComplete在被显示时触发

时间:2014-08-05 09:29:55

标签: c# vb.net datagridview tabcontrol eventhandler

我在标签控件上有一个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

结束班

1 个答案:

答案 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