• 在组合框中嵌入一个DataGridView


    介绍 多栏组合框在W inForms应用程序中非常常见。然而,还没有开源的解决方案能够完全支持数据绑定,并且像DataGridView控件那样可定制。本文的目的是展示如何用相对较少的代码轻松地创建一个。 满足需求的最明显、最直接和最简单的方法是在一个组合框中托管一个DataGridView。这似乎不是一个简单的任务,但实际上它是惊人的容易做(至少在做了它之后)。 本文和提供的源代码更多的是“概念验证”类型,而不是完成的控件。有许多细节不是很“技术”和美学。另一方面,我在我的一个开源程序中使用它(DevExpress是不可能的),它对我的目的来说工作得很好。 这也是我的第一篇关于编程的文章,所以请原谅我糟糕的风格 Background  本文基于以下几篇文章提出的想法: 灵活的组合框和编辑控件使用ToolStripControlHost。MSDN文章如何:主机控件在Windows窗体DataGridView单元格-创建自定义的DataGridViewColumn。 首先创建一个自定义ToolStripControlHost,然后使用它来创建自定义组合框,该组合框又用于创建IDataGridViewEditingControl、自定义DataGridViewCell和自定义DataGridViewColumn。 使用code  使用提供的自定义AccGridComboBox和DataGridViewAccGridComboBoxColumn类就像使用ComboBox和DataGridViewColumn本身一样简单。 您所需要的是添加一个AccGridComboBox或一个datgridcomboboxcolumn到一个表单,就像您将添加一个ComboBox或一个DataGridViewColumn并分配一个相应的DataGridView而不是datasource:

    ' for columns    
    DataGridViewAccGridComboBoxColumn1.ComboDataGridView = ProgramaticalyCreatedDataGridView
    ' selection is done by single click, i.e. not double click
    DataGridViewAccGridComboBoxColumn1.CloseOnSingleClick = True
    ' binding is trigered on value change, i.e. not on validating
    DataGridViewAccGridComboBoxColumn1.InstantBinding = True
    
    ' for comboboxes (second param is CloseOnSingleClick property setter)
    AccGridComboBox1.AddDataGridView(ProgramaticalyCreatedDataGridView, True)
    AccGridComboBox1.InstantBinding = True

    快速,自我解释的例子,如何以编程方式创建一个DataGridView:

    Public Function CreateDataGridViewForPersonInfo(ByVal TargetForm As Form, _
            ByVal ListBindingSource As BindingSource) As DataGridView
     
        ' create the resulting grid and it's columns
        Dim result As New DataGridView
        Dim DataGridViewTextBoxColumn1 As New System.Windows.Forms.DataGridViewTextBoxColumn
        Dim DataGridViewTextBoxColumn2 As New System.Windows.Forms.DataGridViewTextBoxColumn
    
        ' begin initialization (to minimize events)
        CType(result, System.ComponentModel.ISupportInitialize).BeginInit()
    
        ' setup grid properties as you need
        result.AllowUserToAddRows = False
        result.AllowUserToDeleteRows = False
        result.AutoGenerateColumns = False
        result.AllowUserToResizeRows = False
        result.ColumnHeadersVisible = False
        result.RowHeadersVisible = False
        result.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
        result.ReadOnly = True
        result.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect
        result.Size = New System.Drawing.Size(300, 220)
        result.AutoSize = False
        
        ' add datasource
        result.DataSource = ListBindingSource
        
        ' add columns
        result.Columns.AddRange(New System.Windows.Forms.DataGridViewColumn() _
            {DataGridViewTextBoxColumn1, DataGridViewTextBoxColumn2})
        
        ' setup columns as you need
        DataGridViewTextBoxColumn1.AutoSizeMode = _
             System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill
        DataGridViewTextBoxColumn1.DataPropertyName = "Name"
        DataGridViewTextBoxColumn1.HeaderText = "Name"
        DataGridViewTextBoxColumn1.Name = ""
        DataGridViewTextBoxColumn1.ReadOnly = True
    
        DataGridViewTextBoxColumn2.DataPropertyName = "Code"
        DataGridViewTextBoxColumn2.HeaderText = "Code"
        DataGridViewTextBoxColumn2.Name = ""
        DataGridViewTextBoxColumn2.ReadOnly = True
        DataGridViewTextBoxColumn2.AutoSizeMode = DataGridViewAutoSizeColumnMode.NotSet
    
        ' assign binding context of the form that hosts
        ' the control in order to enable databinding
        result.BindingContext = TargetForm.BindingContext
    
        ' end initialization
        CType(result, System.ComponentModel.ISupportInitialize).EndInit()
        
        Return result
    
    End Function

    的兴趣点 创建自定义ToolStripControlHost 控件的基本部分是继承ToolStripControlHost的ToolStripDataGridView类。ToolStripDataGridView类提供了4个新的自解释属性:CloseOnSingleClick、DataGridViewControl、MinDropDownWidth和DropDownHeight。目前我把MinDropDownWidth和DropDownHeight属性设置为只读。它们的值在构造函数中由对应的DataGridView属性的宽度和高度设置,以便在网格创建代码中限制所有网格区域定制代码。尽管这只是个人偏好的问题。 ToolStripDataGridView类订阅和取消订阅子DataGridView事件使用ToolStripControlHost保护覆盖子OnSubscribeControlEvents和OnUnsubscribeControlEvents:

    ' Subscribe and unsubscribe the control events you wish to expose.
    Protected Overrides Sub OnSubscribeControlEvents(ByVal c As Control)
        
        ' Call the base so the base events are connected.
        MyBase.OnSubscribeControlEvents(c)
        
        Dim nDataGridView As DataGridView = DirectCast(c, DataGridView)
    
        ' Add the events:
        ' to highlight the item that is currently under the mouse pointer
        AddHandler nDataGridView.CellMouseEnter, AddressOf OnDataGridViewCellMouseEnter
        ' to accept selection by enter key
        AddHandler nDataGridView.KeyDown, AddressOf OnDataGridViewKeyDown
        ' to accept selection by double clicking
        AddHandler nDataGridView.CellDoubleClick, AddressOf myDataGridView_DoubleClick
        ' to accept selection by single click (if CloseOnSingleClick is set tor TRUE)
        AddHandler nDataGridView.CellClick, AddressOf myDataGridView_Click
    
    End Sub
    
    Protected Overrides Sub OnUnsubscribeControlEvents(ByVal c As Control)
        
        ' Call the base method so the basic events are unsubscribed.
        MyBase.OnUnsubscribeControlEvents(c)
    
        Dim nDataGridView As DataGridView = DirectCast(c, DataGridView)
     
        ' Remove the events.
        RemoveHandler nDataGridView.CellMouseEnter, AddressOf OnDataGridViewCellMouseEnter
        RemoveHandler nDataGridView.KeyDown, AddressOf OnDataGridViewKeyDown
        RemoveHandler nDataGridView.CellDoubleClick, AddressOf myDataGridView_DoubleClick
        RemoveHandler nDataGridView.CellClick, AddressOf myDataGridView_Click
    
    End Sub

    这些事件相当琐碎且不言自明。项目的选择是通过调用:

    DirectCast(Me.Owner, ToolStripDropDown).Close(ToolStripDropDownCloseReason.ItemClicked)

    当父工具stripdatagridview被调整大小时,OnBoundsChanged和Dispose subs被覆盖以调整子DataGridView的大小,当父工具stripdatagridview被释放时,将释放子DataGridView:

    Protected Overrides Sub OnBoundsChanged()
        MyBase.OnBoundsChanged()
        If Not Me.Control Is Nothing Then
            DirectCast(Control, DataGridView).Size = Me.Size
            DirectCast(Control, DataGridView).AutoResizeColumns()
        End If
    End Sub
    
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        MyBase.Dispose(disposing)
        If Not Me.Control Is Nothing AndAlso Not _
           DirectCast(Control, DataGridView).IsDisposed Then Control.Dispose()
    End Sub

    这差不多就是关于ToolStripDataGridView类的全部内容了:一个构造函数、四个普通属性、四个普通事件处理程序和四个简单重写。包括空格在内共有109行代码。 创建自定义组合框 控件的下一个重要部分是AccGridComboBox类本身,它显然继承自ComboBox。 AccGridComboBox类有一个私有变量myDropDown作为ToolStripDropDown,它在类构造函数中实例化,充当ToolStripDataGridView的容器。ToolStripDataGridView本身的实例是由AddDataGridView子程序设置的:

    Public Sub AddDataGridView(ByVal nDataGridView As DataGridView, ByVal nCloseOnSingleClick As Boolean)
        If Not myDataGridView Is Nothing Then Throw New Exception( _
            "Error. DataGridView is already assigned to the AccGridComboBox.")
        myDataGridView = New ToolStripDataGridView(nDataGridView, nCloseOnSingleClick)
        myDropDown.Width = Math.Max(Me.Width, myDataGridView.MinDropDownWidth)
        myDropDown.Height = nDataGridView.Height
        myDropDown.Items.Clear()
        myDropDown.Items.Add(Me.myDataGridView)
    End Sub

    AccGridComboBox处理通过覆盖WndProc和拦截消息显示下拉列表。此方法的当前实现是从CodeProject文章Flexible ComboBox和EditingControl中复制的,如果需要手动输入支持,应该对其进行更改,因为它捕获了ComboBox所有区域的单击,从而阻止了文本输入。

    Private Const WM_LBUTTONDOWN As UInt32 = &H201
    Private Const WM_LBUTTONDBLCLK As UInt32 = &H203
    Private Const WM_KEYF4 As UInt32 = &H134
    
    Protected Overrides Sub WndProc(ByRef m As Message)
    
        '#Region "WM_KEYF4"
        If m.Msg = WM_KEYF4 Then
            Me.Focus()
            Me.myDropDown.Refresh()
            If Not Me.myDropDown.Visible Then
    
                ShowDropDown()
    
            Else
                myDropDown.Close()
    
            End If
            Return
        End If
        '#End Region
    
        '#Region "WM_LBUTTONDBLCLK"
        If m.Msg = WM_LBUTTONDBLCLK OrElse m.Msg = WM_LBUTTONDOWN Then
            If Not Me.myDropDown.Visible Then
    
                ShowDropDown()
    
            Else
                myDropDown.Close()
    
            End If
            Return
        End If
        '#End Region
    
        MyBase.WndProc(m)
    
    End Sub

    实际上显示下拉列表的AccGridComboBox方法主要处理下拉列表大小和选择适当的DataGridView行(保存当前的SelectedValue)。

    Private Sub ShowDropDown()
            
        ' if a DataGridView is assigned
        If Not Me.myDataGridView Is Nothing Then
            
            ' just in case, though such situation is not supposed to happen
            If Not myDropDown.Items.Contains(Me.myDataGridView) Then
                myDropDown.Items.Clear()
                myDropDown.Items.Add(Me.myDataGridView)
            End If
    
            ' do sizing
            myDropDown.Width = Math.Max(Me.Width, Me.myDataGridView.MinDropDownWidth)
            myDataGridView.Size = myDropDown.Size
            myDataGridView.DataGridViewControl.Size = myDropDown.Size
            myDataGridView.DataGridViewControl.AutoResizeColumns()
    
            ' select DataGridViewRow that holds the currently selected value
            If _SelectedValue Is Nothing OrElse IsDBNull(_SelectedValue) Then
                myDataGridView.DataGridViewControl.CurrentCell = Nothing
    
            ElseIf Not Me.ValueMember Is Nothing AndAlso _
                       Not String.IsNullOrEmpty(Me.ValueMember.Trim) Then
    
                ' If ValueMember is set, look for the value by reflection
                
                If myDataGridView.DataGridViewControl.Rows.Count < 1 OrElse _
                    myDataGridView.DataGridViewControl.Rows(0).DataBoundItem Is Nothing OrElse _
                    myDataGridView.DataGridViewControl.Rows(0).DataBoundItem.GetType. _
                    GetProperty(Me.ValueMember.Trim, _
                      BindingFlags.Public OrElse BindingFlags.Instance) Is Nothing Then
    
                    myDataGridView.DataGridViewControl.CurrentCell = Nothing
    
                Else
    
                    Dim CurrentValue As Object
                    For Each r As DataGridViewRow In myDataGridView.DataGridViewControl.Rows
                        If Not r.DataBoundItem Is Nothing Then
                            CurrentValue = GetValueMemberValue(r.DataBoundItem)
                            If _SelectedValue = CurrentValue Then
                                myDataGridView.DataGridViewControl.CurrentCell = _
                                    myDataGridView.DataGridViewControl.Item(0, r.Index)
                                Exit For
                            End If
                        End If
                    Next
    
                End If
    
            Else
     
                ' If ValueMember is NOT set, look for the value by value or 
                
                Dim SelectionFound As Boolean = False
                For Each r As DataGridViewRow In myDataGridView.DataGridViewControl.Rows
                    Try
                        ' try by value because it's faster and lookup
                        ' objects usualy implement equal operators
                        If _SelectedValue = r.DataBoundItem Then
                            myDataGridView.DataGridViewControl.CurrentCell = _
                                myDataGridView.DataGridViewControl.Item(0, r.Index)
                            SelectionFound = True
                            Exit For
                        End If
                    Catch ex As Exception
                        Try
                            If _SelectedValue Is r.DataBoundItem Then
                                myDataGridView.DataGridViewControl.CurrentCell = _
                                    myDataGridView.DataGridViewControl.Item(0, r.Index)
                                SelectionFound = True
                                Exit For
                            End If
                        Catch e As Exception
                        End Try
                    End Try
                Next
                If Not SelectionFound Then _
                           myDataGridView.DataGridViewControl.CurrentCell = Nothing
    
            End If
    
            myDropDown.Show(Me, CalculatePoz) 
    
        End If
    
    End Sub
        
    ' Helper method, tries geting ValueMember property value by reflection
    Private Function GetValueMemberValue(ByVal DataboundItem As Object) As Object
        Dim newValue As Object = Nothing
        Try
            newValue = DataboundItem.GetType.GetProperty(Me.ValueMember.Trim, BindingFlags.Public _
                OrElse BindingFlags.Instance).GetValue(DataboundItem, Nothing)
        Catch ex As Exception
        End Try
        Return newValue
    End Function
    
    ' Helper method, takes care of dropdown fitting the window
    Private Function CalculatePoz() As Point
    
        Dim point As New Point(0, Me.Height)
    
        If (Me.PointToScreen(New Point(0, 0)).Y + Me.Height + Me.myDataGridView.Height) _
            > Screen.PrimaryScreen.WorkingArea.Height Then
            point.Y = -Me.myDataGridView.Height - 7
        End If
    
        Return point
    
    End Function

    AccGridComboBox通过重载SelectedValue属性来处理当前值的设置(以绕过本地的ComboBox逻辑),并提供定制的setter方法来允许通过ValueMember设置值对象。

    Private Sub SetValue(ByVal value As Object, ByVal IsValueMemberValue As Boolean)
    
        If value Is Nothing Then
            Me.Text = ""
            _SelectedValue = Nothing
    
        Else
    
            If Me.ValueMember Is Nothing OrElse String.IsNullOrEmpty(Me.ValueMember.Trim) _
                OrElse IsValueMemberValue Then
    
                Me.Text = value.ToString
                _SelectedValue = value
    
            Else
    
                Dim newValue As Object = GetValueMemberValue(value)
    
                ' If getting the ValueMember property value fails, try setting the object itself
                If newValue Is Nothing Then
                    Me.Text = value.ToString
                    _SelectedValue = value
                Else
                    Me.Text = newValue.ToString
                    _SelectedValue = newValue
                End If
    
            End If
    
        End If
    
    End Sub
    
    Private Sub ToolStripDropDown_Closed(ByVal sender As Object, _
                ByVal e As ToolStripDropDownClosedEventArgs)
        If e.CloseReason = ToolStripDropDownCloseReason.ItemClicked Then
            If Not MyBase.Focused Then MyBase.Focus()
            If myDataGridView.DataGridViewControl.CurrentRow Is Nothing Then
                SetValue(Nothing, False)
            Else
                SetValue(myDataGridView.DataGridViewControl.CurrentRow.DataBoundItem, False)
            End If
            MyBase.OnSelectedValueChanged(New EventArgs)
            ' If InstantBinding property is set to TRUE, force binding.
            If _InstantBinding Then
                For Each b As Binding In MyBase.DataBindings
                    b.WriteValue()
                Next
            End If
        End If
    End Sub

    从上面的代码中可以看到,AccGridComboBox也实现了一个自定义属性InstantBinding。它本身并不是必需的,但在某些情况下,最好在值更改时而不是在验证时更新绑定。 这就是组合控件本身需要的所有代码,但为了让它准备好作为IDataGridViewEditingControl使用,你需要实现更多的方法:

    Protected Overridable ReadOnly Property DisposeToolStripDataGridView() As Boolean
        Get
            Return True
        End Get
    End Property
    
    Friend Sub AddToolStripDataGridView(ByVal nToolStripDataGridView As ToolStripDataGridView)
        If nToolStripDataGridView Is Nothing OrElse (Not myDataGridView Is Nothing _
            AndAlso myDataGridView Is nToolStripDataGridView) Then Exit Sub
        myDataGridView = nToolStripDataGridView
        myDropDown.Width = Math.Max(Me.Width, myDataGridView.MinDropDownWidth)
        myDropDown.Height = myDataGridView.DropDownHeight
        myDropDown.Items.Clear()
        myDropDown.Items.Add(Me.myDataGridView)
    End Sub
    
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If components IsNot Nothing Then components.Dispose()
            If DisposeToolStripDataGridView Then
                If Not myDropDown Is Nothing AndAlso Not _
                          myDropDown.IsDisposed Then myDropDown.Dispose()
                If Not myDataGridView Is Nothing AndAlso _
                    Not myDataGridView.DataGridViewControl Is Nothing AndAlso _
                    Not myDataGridView.DataGridViewControl.IsDisposed Then _
                    myDataGridView.DataGridViewControl.Dispose()
                If Not myDataGridView Is Nothing AndAlso Not myDataGridView.IsDisposed Then _
                    myDataGridView.Dispose()
            ElseIf Not DisposeToolStripDataGridView AndAlso Not myDropDown Is Nothing _
                 AndAlso Not myDropDown.IsDisposed Then
                If Not myDataGridView Is Nothing Then myDropDown.Items.Remove(myDataGridView)
                myDropDown.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    如果你有一个独立的AccGridComboBox,合理的处理托管的ToolStripDropDown, ToolStripDataGridView,和DataGridView实例在一起将组合本身作为DataGridView实例的er不能跨不同表单重用。另一方面,如果您有一个AccGridComboBox实例作为DataGridView列的一部分,那么您需要为列的生存期而不是组合生存期保留DataGridView实例(组合实例在列生存期期间被释放)。要实现这两种受保护的可重写行为,使用了DisposeToolStripDataGridView属性。此属性指示Dispose方法是否也应该释放ToolStripDataGridView和DataGridView实例。它总是返回true,除非被重写。它在AccGridComboBoxEditingControl类中被重写,这个类被自定义DataGridViewCell使用。 创建自定义的IDataGridViewEditingControl、DataGridViewCell和DataGridViewColumn 创建自定义DataGridViewColumn的过程在MSDN文章“如何:宿主Windows Forms DataGridView单元格中的控件”中有详细介绍。所以我将只讨论特定于AccGridComboBox实现的代码部分。 在AccGridComboBoxEditingControl类的实现中,与前面提到的MSDN文章中描述的实现相比,只有少数几种具体的方法。这个类需要像前面讨论的那样重写DisposeToolStripDataGridView属性,以防止处理DataGridView。这个类还需要处理SelectedValueChanged事件,并通知DataGridView基础设施的更改。最终值到/从文本的转换是由基类AccGridComboBox处理的,因此GetEditingControlFormattedValue的实现只包含一个对文本属性的引用。

    Protected Overrides ReadOnly Property DisposeToolStripDataGridView() As Boolean
        Get
            Return False
        End Get
    End Property
    
    Private Sub SelectedValueChangedHandler(ByVal sender As Object, _
                ByVal e As EventArgs) Handles Me.SelectedValueChanged
        If Not _hasValueChanged Then
            _hasValueChanged = True
            _dataGridView.NotifyCurrentCellDirty(True)
        End If
    End Sub
    
    Public Function GetEditingControlFormattedValue(ByVal context As DataGridViewDataErrorContexts) _
           As Object Implements _
           System.Windows.Forms.IDataGridViewEditingControl.GetEditingControlFormattedValue
        Return Me.Text
    End Function

    在AccGridComboBoxDataGridViewCell类的实现中,只有少数具体的方法可以与前面提到的MSDN文章中描述的实现进行比较。由于此单元格将处理不同的对象类型,所以ValueType属性将返回最通用的类型- object。另外两个方法是自解释的,负责初始化AccGridComboBox编辑控件,获取和设置单元格值。

    Public Overrides ReadOnly Property ValueType() As Type
        Get
            Return GetType(Object)
        End Get
    End Property
     
    Public Overrides Sub InitializeEditingControl(ByVal nRowIndex As Integer, _
        ByVal nInitialFormattedValue As Object, ByVal nDataGridViewCellStyle As DataGridViewCellStyle)
    
        MyBase.InitializeEditingControl(nRowIndex, nInitialFormattedValue, nDataGridViewCellStyle)
    
        Dim cEditBox As AccGridComboBox = TryCast(Me.DataGridView.EditingControl, AccGridComboBox)
    
        If cEditBox IsNot Nothing Then
    
            If Not MyBase.OwningColumn Is Nothing AndAlso Not DirectCast(MyBase.OwningColumn, _
                DataGridViewAccGridComboBoxColumn).ComboDataGridView Is Nothing Then
    
                ' Add the common column ToolStripDataGridView and set common properties
                cEditBox.AddToolStripDataGridView(DirectCast(MyBase.OwningColumn, _
                    DataGridViewAccGridComboBoxColumn).GetToolStripDataGridView)
                cEditBox.ValueMember = DirectCast(MyBase.OwningColumn, _
                         DataGridViewAccGridComboBoxColumn).ValueMember
                cEditBox.InstantBinding = DirectCast(MyBase.OwningColumn, _
                         DataGridViewAccGridComboBoxColumn).InstantBinding
    
                End If
     
            ' try to set current value
            Try
                cEditBox.SelectedValue = Value
            Catch ex As Exception
                cEditBox.SelectedValue = Nothing
            End Try
    
        End If
    
    End Sub
    
    Protected Overrides Function SetValue(ByVal rowIndex As Integer, ByVal value As Object) As Boolean
        If Not Me.DataGridView Is Nothing AndAlso Not Me.DataGridView.EditingControl Is Nothing _
            AndAlso TypeOf Me.DataGridView.EditingControl Is AccGridComboBox Then
            Return MyBase.SetValue(rowIndex, DirectCast(Me.DataGridView.EditingControl, _
                AccGridComboBox).SelectedValue)
        Else
            Return MyBase.SetValue(rowIndex, value)
        End If
    End Function

    最后,DataGridViewAccGridComboBoxColumn类只实现映射AccGridComboBox属性的属性,并负责处理相关的网格:

    Private myDataGridView As ToolStripDataGridView = Nothing
    Public Property ComboDataGridView() As DataGridView
        Get
            If Not myDataGridView Is Nothing Then Return myDataGridView.DataGridViewControl
            Return Nothing
        End Get
        Set(ByVal value As DataGridView)
            If Not value Is Nothing Then
                myDataGridView = New ToolStripDataGridView(value, _CloseOnSingleClick)
            Else
                myDataGridView = Nothing
            End If
        End Set
    End Property
    
    Private _ValueMember As String = ""
    Public Property ValueMember() As String
        Get
            Return _ValueMember
        End Get
        Set(ByVal value As String)
            _ValueMember = value
        End Set
    End Property
    
    Private _CloseOnSingleClick As Boolean = True
    Public Property CloseOnSingleClick() As Boolean
        Get
            Return _CloseOnSingleClick
        End Get
        Set(ByVal value As Boolean)
            _CloseOnSingleClick = value
            If Not myDataGridView Is Nothing Then _
               myDataGridView.CloseOnSingleClick = value
        End Set
    End Property
    
    Private _InstantBinding As Boolean = True
    Public Property InstantBinding() As Boolean
        Get
            Return _InstantBinding
        End Get
        Set(ByVal value As Boolean)
            _InstantBinding = value
        End Set
    End Property
    
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not myDataGridView Is Nothing _
                AndAlso Not myDataGridView.DataGridViewControl Is Nothing _
                AndAlso Not myDataGridView.DataGridViewControl.IsDisposed Then _
                myDataGridView.DataGridViewControl.Dispose()
            If Not myDataGridView Is Nothing AndAlso Not myDataGridView.IsDisposed Then _
                myDataGridView.Dispose()
        End If
        MyBase.Dispose(disposing)
    End Sub

    本文转载于:http://www.diyabc.com/frontweb/news386.html

  • 相关阅读:
    再见了亲爱的学生们,再见了敬爱的同事们,再见了信狮
    #if defined 和#ifdef的区别
    C# ASP.NET Core开发学生信息管理系统(二)
    modelsim与debussy联合的问题
    C#批量生成大数据量无重复随机数据的另类高效实现
    DataColumn.Caption属性应用到DataGridView.HeaderText的方法
    [转载]安装网银安全控件
    近期学习SQL Server,收藏的几个学习教程网址备忘
    asp.net根据域名查ip C#版
    asp.net 2.0教程 成员资格和角色管理
  • 原文地址:https://www.cnblogs.com/Dincat/p/13443972.html
Copyright © 2020-2023  润新知