如何通过第二个小按钮扩展DataGridView ComboBox列的编辑控件?

时间:2011-07-12 14:55:14

标签: vb.net winforms datagridview combobox

我在DataGridViewComboBoxColumn中插入DataViewGrid列。这很好。

现在,我希望用户不仅能够选择一个列表项,而且能够“钻取”到组合框后面的列表中,允许他编辑(插入/删除/更新)列表。

我认为在组合框的下拉按钮后面显示一个“..”按钮是个好主意。推送它会导致可以维护列表的对话框。

我磕磕绊绊的是:

  1. 如何创建这样的自定义组合框? ComboBox(组合框列创建的组合框的基础作为其编辑控件)是否足以容纳此组合框?一个额外的按钮?什么是小屁股的容器 - ComboBox后裔?
  2. 如何让网格创建并处理这样的自定义组合框?
  3. 我目前尝试通过在DataGridViewComboBoxColum分配中使用DataGridViewComboBoxCell后代进行子类化CellTemplate来解决此问题,并覆盖PositionWEditingPanelPositionEditingControl来操纵面板和组合框的大小,所以我有空间的小按钮。 这是正确的方法吗?

    或者我是否必须创建一个DataGridViewColumn后代,创建一个包含DataGridView组合框编辑控件和小按钮的Panel?我如何确保列保持组合框的关注,以便它具有正确的项目等?

    也许我听起来很困惑,但我可能是经过几周的VB代码(doh)....

1 个答案:

答案 0 :(得分:1)

这是我提出的代码。只有缺少的是按钮按下事件处理程序。

欢迎改进!

#Region "Custom column, cell and edit control for Combobox-with-a-'..'-Button"


Public Class DataGridViewComboBoxExColumn
  Inherits DataGridViewComboBoxColumn
  Public Sub New()
    MyBase.New()
    CellTemplate = New DataGridViewComboBoxExCell()
  End Sub
  Public Overrides Property CellTemplate As DataGridViewCell
    Get
      Return MyBase.CellTemplate
    End Get
    Set(ByVal value As DataGridViewCell)
      If (value IsNot Nothing) AndAlso Not value.GetType().IsAssignableFrom(GetType(DataGridViewComboBoxExCell)) Then
        Throw New InvalidCastException("Must be a DataGridViewComboBoxExCell")
      End If
      MyBase.CellTemplate = value
    End Set
  End Property
End Class

Public Class DataGridViewComboBoxExCell
  Inherits DataGridViewComboBoxCell
  Dim HostingPanel As Panel

  Public Sub New()
    MyBase.New()
    Dim TheButton As Button
    HostingPanel = New Panel
    HostingPanel.BorderStyle = BorderStyle.Fixed3D
    HostingPanel.Padding = New Padding(0, 0, 0, 0)

    HostingPanel.BackColor = Color.FromKnownColor(KnownColor.Control)
    'HostingPanel.ForeColor = Color.Red ' Color.FromKnownColor(KnownColor.ButtonFace)
    TheButton = New Button
    TheButton.Text = ""
    TheButton.BackColor = Color.FromKnownColor(KnownColor.ButtonFace)
    TheButton.ImageList = DaCorFredProtMainForm.MainImageList
    TheButton.ImageKey = "table_edit.png"

    TheButton.Dock = DockStyle.Fill
    HostingPanel.Controls.Add(TheButton)
  End Sub

  Public Overrides Sub InitializeEditingControl(ByVal rowIndex As Integer, ByVal initialFormattedValue As Object, ByVal dataGridViewCellStyle As DataGridViewCellStyle)
    MyBase.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle)
    If Not Me.DataGridView.EditingPanel.Controls.Contains(HostingPanel) Then ' Should always be true
      Me.DataGridView.EditingPanel.Controls.Add(HostingPanel)
    End If
  End Sub

  Public Overrides Sub DetachEditingControl()
    If Me.DataGridView.EditingPanel.Controls.Contains(HostingPanel) Then ' Should always be true
      Me.DataGridView.EditingPanel.Controls.Remove(HostingPanel)
    End If
    MyBase.DetachEditingControl()
  End Sub

  Public Overrides ReadOnly Property EditType As Type
    Get
      Return MyBase.EditType
    End Get
  End Property

  Public Overrides ReadOnly Property ValueType As Type
    Get
      Return MyBase.ValueType
    End Get
  End Property

  Public Overrides Function PositionEditingPanel(ByVal cellBounds As System.Drawing.Rectangle, ByVal cellClip As System.Drawing.Rectangle, ByVal cellStyle As System.Windows.Forms.DataGridViewCellStyle, ByVal singleVerticalBorderAdded As Boolean, ByVal singleHorizontalBorderAdded As Boolean, ByVal isFirstDisplayedColumn As Boolean, ByVal isFirstDisplayedRow As Boolean) As System.Drawing.Rectangle
    cellBounds.Width += cellBounds.Height
    cellClip.Width += cellClip.Height
    Return MyBase.PositionEditingPanel(cellBounds, cellClip, cellStyle, singleVerticalBorderAdded, singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow)
  End Function

  Public Overrides Sub PositionEditingControl(ByVal setLocation As Boolean, ByVal setSize As Boolean, ByVal cellBounds As System.Drawing.Rectangle, ByVal cellClip As System.Drawing.Rectangle, ByVal cellStyle As System.Windows.Forms.DataGridViewCellStyle, ByVal singleVerticalBorderAdded As Boolean, ByVal singleHorizontalBorderAdded As Boolean, ByVal isFirstDisplayedColumn As Boolean, ByVal isFirstDisplayedRow As Boolean)
    MyBase.PositionEditingControl(setLocation, setSize, cellBounds, cellClip, cellStyle, singleVerticalBorderAdded, singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow)
    Me.DataGridView.EditingControl.Width -= Me.DataGridView.EditingPanel.Height
    HostingPanel.Width = Me.DataGridView.EditingPanel.Height
    HostingPanel.Height = Me.DataGridView.EditingPanel.Height
    HostingPanel.Location = New Point(DataGridView.EditingPanel.Size.Width - DataGridView.EditingPanel.Size.Height, 0)
  End Sub
End Class

#End Region