开发者

How can I extend a DataGridView ComboBox column's edit control by a second tiny button?

I insert DataGridViewComboBoxColumn columns in a DataViewGrid. That works fine.

Now, I want the user to be able to not only select one list item, but to "drilldown" into the list that is behind the combobox, allowing him to edit (insert/delete/update) the list.

I think it would be a good idea to display a ".." button right behind the dropdown button of the combobox. Pushing it leads to a dialog where the list can be maintained.

What I am stumbling upon is:

  1. How would I create such a custom combobox? Is ComboBox (which is the base for the combo box that the combo box column creates as its edit control) open enough to accommodate such an additional button? What would be the container of the tiny buttoon -- the ComboBox descendant?
  2. How I would make the grid create and handle such a custom combobox?

I currently try to solve this by subclassing DataGridViewComboBoxColum, using a DataGridViewComboBoxCell descendent in its CellTemplate assignment, and overriding PositionWEditingPanel and PositionEditingControl to manipulate the sizes of the panel and the combobox so I'd have space for the tiny but开发者_如何学编程ton. Is that the correct way?

Or would I have to create a DataGridViewColumn descendant which creates a Panel containing a DataGridView combobox edit control and the tiny button? How would I make sure the column keeps care of the combo box so it has the correct items etc?

Maybe I sound confused, but I probably am after weeks of VB code (doh)....


Here's the code I came up with. Only thing that's missing is the button press event handler.

Improvements welcome!

#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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜