代碼如下:
Public Class DataGridViewTreeViewColumn
Inherits DataGridViewColumn
Public Sub New()
MyBase.New(New DataGridViewTreeViewCell)
End Sub
Public Overrides Property CellTemplate() As System.Windows.Forms.DataGridViewCell
Get
Return MyBase.CellTemplate
End Get
Set(ByVal value As System.Windows.Forms.DataGridViewCell)
If value IsNot Nothing And Not value.GetType.IsAssignableFrom(GetType(DataGridViewTreeViewCell)) Then
Throw New InvalidCastException("不是DataGridViewTreeViewCell")
End If
MyBase.CellTemplate = value
End Set
End Property
End Class
Public Class ComboBoxTreeView
Inherits ComboBox
Private Const WN_LBUTTONDOWN = &H201
Private Const WM_LBUTTONDBLCLK = &H203
Private treeViewHost As ToolStripControlHost
Private Shadows dropDown As ToolStripDropDown
Public Sub New()
Dim treeView As TreeView = New TreeView
AddHandler treeView.AfterSelect, AddressOf Me.treeView_AfterSelect
treeViewHost = New ToolStripControlHost(treeView)
dropDown = New ToolStripDropDown
dropDown.Width = Me.Width
dropDown.Items.Add(treeViewHost)
End Sub
Private Sub treeView_AfterSelect(ByVal sender As Object, ByVal e As TreeViewEventArgs)
Me.Text = TreeView.SelectedNode.text
dropDown.Close()
End Sub
Public ReadOnly Property TreeView() As TreeView
Get
Return CType(treeViewHost.Control, TreeView)
End Get
End Property
Private Sub ShowDropDown()
If dropDown IsNot Nothing Then
treeViewHost.Size = New Size(DropDownWidth, DropDownHeight)
dropDown.Show(Me, 0, Me.Height)
End If
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_LBUTTONDBLCLK Or m.Msg = WN_LBUTTONDOWN Then
Call ShowDropDown()
Else
MyBase.WndProc(m)
End If
End Sub
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If dropDown IsNot Nothing Then
dropDown.Dispose()
dropDown = Nothing
End If
End If
MyBase.Dispose(disposing)
End Sub
End Class
Public Class DataGridViewTreeViewCell
Inherits DataGridViewTextBoxCell
Public Overrides Sub InitializeEditingControl(ByVal rowIndex As Integer, ByVal initialFormattedValue As Object, _
ByVal dataGridViewCellStyle As System.Windows.Forms.DataGridViewCellStyle)
MyBase.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle)
Dim ctl As DataGridViewTreeViewEditingControl = DataGridView.EditingControl
ctl.Text = Me.Value
End Sub
Public Overrides ReadOnly Property EditType() As System.Type
Get
'Return MyBase.EditType
Return GetType(DataGridViewTreeViewEditingControl)
End Get
End Property
Public Overrides ReadOnly Property ValueType() As System.Type
Get
'Return MyBase.ValueType
Return GetType(String)
End Get
End Property
Public Overrides ReadOnly Property DefaultNewRowValue() As Object
Get
'Return MyBase.DefaultNewRowValue
Return ""
End Get
End Property
End Class
Public Class DataGridViewTreeViewEditingControl
Inherits ComboBoxTreeView
Implements System.Windows.Forms.IDataGridViewEditingControl
Protected rowIndex As Integer
Protected dataGridView As DataGridView
Protected ValueChanged As Boolean = False
Protected Overrides Sub OnTextChanged(ByVal e As System.EventArgs)
MyBase.OnTextChanged(e)
NotifyDataGridViewOfValueChange()
End Sub
Private Sub NotifyDataGridViewOfValueChange()
valuechanged = True
DataGridView.NotifyCurrentCellDirty(True)
End Sub
Public ReadOnly Property EditingPanelCursor() As Cursor Implements IDataGridViewEditingControl.EditingPanelCursor
Get
Return Cursors.IBeam
End Get
End Property
Public Property EditingControlDataGridView() As DataGridView Implements IDataGridViewEditingControl.EditingControlDataGridView
Get
Return dataGridView
End Get
Set(ByVal value As DataGridView)
dataGridView = value
End Set
End Property
Public Property EditingControlFormattedValue() As Object Implements IDataGridViewEditingControl.EditingControlFormattedValue
Get
Return Me.Text
End Get
Set(ByVal value As Object)
Me.Text = value.ToString
NotifyDataGridViewOfValueChange()
End Set
End Property
Public Function EditingControlWantsInputKey(ByVal key As Keys, ByVal dataGridViewWantsInputKey As Boolean) As Boolean _
Implements IDataGridViewEditingControl.EditingControlWantsInputKey
Select Case key And Keys.KeyCode
Case Keys.Left, Keys.Up, Keys.Down, Keys.Right, Keys.Home, Keys.End, Keys.PageDown, Keys.PageUp : Return True
Case Else : Return False
End Select
End Function
Public ReadOnly Property RepositionEditingControlOnValueChange() As Boolean Implements IDataGridViewEditingControl.RepositionEditingControlOnValueChange
Get
Return False
End Get
End Property
Public Property EditingControlRowIndex() As Integer Implements IDataGridViewEditingControl.EditingControlRowIndex
Get
Return Me.rowIndex
End Get
Set(ByVal value As Integer)
Me.rowIndex = value
End Set
End Property
Public Sub ApplyCellStyleToEditingControl(ByVal DataGridViewCellStyle As DataGridViewCellStyle) Implements IDataGridViewEditingControl.ApplyCellStyleToEditingControl
Me.Font = DataGridViewCellStyle.Font
Me.ForeColor = DataGridViewCellStyle.ForeColor
Me.BackColor = DataGridViewCellStyle.BackColor
End Sub
Public Property EditingControlValueChanged() As Boolean Implements IDataGridViewEditingControl.EditingControlValueChanged
Get
Return ValueChanged
End Get
Set(ByVal value As Boolean)
Me.ValueChanged = value
End Set
End Property
Public Sub PrepareEditingControlForEdit(ByVal selectAll As Boolean) Implements IDataGridViewEditingControl.PrepareEditingControlForEdit
End Sub
Public Function GetEditingControlFormattedValue(ByVal context As DataGridViewDataErrorContexts) As Object Implements IDataGridViewEditingControl.GetEditingControlFormattedValue
Return Text
End Function
End Class
測試代碼如下:
Public Class Form1
Dim WithEvents dataGridView1 As New DataGridView
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim Column1 As New DataGridViewTreeViewColumn
Column1.HeaderText = "下拉樹列"
With dataGridView1
.Columns.Add(Column1)
.Location = New System.Drawing.Point(0, 0)
.Dock = DockStyle.Fill
.Visible = True
.BackgroundColor = Color.White
End With
Me.Controls.Add(dataGridView1)
End Sub
Private Sub dataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles dataGridView1.EditingControlShowing
Dim dgvTree As DataGridViewTreeViewEditingControl = e.Control
If dgvTree IsNot Nothing Then
For i As Integer = 0 To 5
Dim root As TreeNode = New TreeNode("TestNode" + i.ToString)
root.Nodes.Add("Node1")
root.Nodes.Add("Node2")
root.Nodes.Add("Node3")
root.Nodes.Add("Node4")
dgvTree.TreeView.Nodes.Add(root)
Next
End If
End Sub
End Class