自定義控件之DataGridView列(下拉列表樹)

效果圖如下:


代碼如下:
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
發佈了38 篇原創文章 · 獲贊 4 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章