WinForms:处理关键字在自定义DataGridViewColumn事件

时间:2015-06-23 09:23:46

标签: .net vb.net winforms datagridview

摘要: VB.NET具有用于附加事件处理程序的handles子句。当事件属于自定义DataGridViewColumn时,每次使用DataGridView的“编辑列”对话框时,WinForms设计器都会从代码中删除此子句。

长版本:我通过派生DataGridViewColumn类实现了一个简单的DataGridViewButtonColumn。它只是添加一个事件GetImage,由单元格的绘制逻辑使用(单元格代码与问题无关)。

Public Class DataGridViewAdvButtonColumn
    Inherits DataGridViewButtonColumn

    Public Sub New()
        Me.CellTemplate = New DataGridViewAdvButtonCell
    End Sub

    Public Event GetImage(ByVal rowIndex As Integer, ByRef image As Image)

    Friend Sub OnGetImage(ByVal rowIndex As Integer, ByRef image As Image)
        RaiseEvent GetImage(rowIndex, image)
    End Sub

    Public Overrides Function Clone() As Object
        Return TryCast(MyBase.Clone, DataGridViewAdvButtonColumn)
    End Function

End Class

现在假设我在特定表单上使用此列类型,并且我将处理程序附加到GetImage事件,如下所示:

Private Sub column_GetImage(rowIndex As Integer, ByRef image As Image) Handles column.GetImage
    ' ...
End Sub

我遇到的问题是,只要我打开托管列的handles的“编辑列”对话框,WinForms设计器就会删除DataGridView子句。结果:

Private Sub column_GetImage(rowIndex As Integer, ByRef image As Image) 
    ' ...
End Sub

显然不会发生这种情况。这是非常危险的,因为它几乎不被注意(不会产生编译器错误)。

我已经尝试将代码添加到列的Clone方法,以复制附加的事件处理程序。但是,这并没有改变任何东西(我注意到在设计时没有附加事件)。我还尝试使用e As GetImageEventArgs代替ByRef image As Image将事件的签名更改为更“常规”的内容;没有帮助。

这应该是一个常见的问题,但似乎没有人似乎在他们的自定义DataGridViewColumns上使用自定义事件。所以谷歌也没有发现任何事情。

重现的步骤:要回答用户Plutonix的问题,请在此处重现此步骤的详细步骤(使用严格选项编译)。

  • 创建一个WinForms项目。
  • DataGridViewAdvButtonColumn类(上面的代码)添加到项目
  • DataGridViewAdvButtonCell类(下面的代码)添加到项目
  • 编译
  • 使用设计器将DataGridView添加到Form1.vb表单。
  • 使用设计器向DataGridViewAdvButtonColumn
  • 添加DataGridView类型的新列
  • 在属性编辑器中选择列,单击事件图标(以便列出所有事件),然后双击GetImage事件。
  • 您现在位于带有事件处理程序的表单的代码隐藏中,如上例所示。
  • 回到设计师那里;将另一列(类型无​​关紧要)添加到DataGridView
  • 回到代码隐藏。您将看到上一步中添加的事件处理程序的handles语句现已消失。 QED

以下是DataGridViewAdvButtonCell的代码:

Public Class DataGridViewAdvButtonCell
    Inherits DataGridViewButtonCell

    Public Overrides Function Clone() As Object
        Return TryCast(MyBase.Clone, DataGridViewButtonCell)
    End Function

    Protected Overrides Sub Paint(graphics As Graphics, clipBounds As Rectangle, cellBounds As Rectangle,
                                  rowIndex As Integer, cellState As DataGridViewElementStates, value As Object, formattedValue As Object,
                                  errorText As String, cellStyle As DataGridViewCellStyle, advancedBorderStyle As DataGridViewAdvancedBorderStyle,
                                  paintParts As DataGridViewPaintParts)

        MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts)

        ' Fire GetImage event
        Dim image As Image = Nothing
        DirectCast(OwningColumn, DataGridViewAdvButtonColumn).OnGetImage(rowIndex, image)
        If image IsNot Nothing Then
            ' do something..
        End If
    End Sub

End Class

1 个答案:

答案 0 :(得分:0)

如果你无法弄清楚为什么会这样,你至少可以通过使用Addhandler在代码中自己添加处理程序来避免这个问题。我知道它不太理想但如果设计师没有正常工作,它可能是保证让处理程序在运行时工作的唯一方法。

AddHandler column.GetImage, Addressof column_GetImage