自定义控件之带有树型控件的下拉列表框

效果图如下:



代码如下:
Public   Delegate   Sub NodeSelectEventHandler()

Public Class ComboBoxTree
    
Inherits UserControl

    
Private pnlBack As Panel
    
Private pnlTree As Panel
    
Private tbSelectedValue As TextBox
    
Private btnSelect As ButtonEx
    
Private tvTreeView As TreeView
    
Private lblSizingGrip As LabelEx
    
Private frmTreeView As Form

    
Private _branchSeparator As String
    
Private _absoluteChildrenSelectableOnly As Boolean
    
Private DragOffset As System.Drawing.Point


    
Public ReadOnly Property Nodes() As TreeNodeCollection
        
Get
            
Return Me.tvTreeView.Nodes
        
End Get
    
End Property


    
Public WriteOnly Property SelectedNode() As TreeNode
        
Set(ByVal value As TreeNode)
            
Me.tvTreeView.SelectedNode = value
        
End Set
    
End Property


    
Public Overrides Property text() As String
        
Get
            
Return Me.tbSelectedValue.Text
        
End Get
        
Set(ByVal value As String)
            
Me.tbSelectedValue.Text = value
        
End Set
    
End Property


    
Public Property BranchSeparator() As String
        
Get
            
Return Me._branchSeparator
        
End Get
        
Set(ByVal value As String)
            
If value.Length > 0 Then Me._branchSeparator = value
        
End Set
    
End Property


    
Public Property AbsoluteChildrenSelectableOnly() As Boolean
        
Get
            
Return Me._absoluteChildrenSelectableOnly
        
End Get
        
Set(ByVal value As Boolean)
            
Me._absoluteChildrenSelectableOnly = value
        
End Set
    
End Property



    
Public Sub New()
        InitializeComponent()

        
Me.pnlBack = New Panel
        
Me.pnlBack.BorderStyle = Windows.Forms.BorderStyle.Fixed3D
        
Me.pnlBack.BackColor = Color.White
        
Me.pnlBack.AutoScroll = False

        
Me.tbSelectedValue = New TextBox
        
Me.tbSelectedValue.BorderStyle = Windows.Forms.BorderStyle.None

        
Me.btnSelect = New ButtonEx
        
AddHandler Me.btnSelect.Click, AddressOf Me.ToggleTreeView
        
Me.btnSelect.FlatStyle = FlatStyle.Flat

        
Me.lblSizingGrip = New LabelEx
        
Me.lblSizingGrip.Size = New Size(99)
        
Me.lblSizingGrip.BackColor = Color.Transparent
        
Me.lblSizingGrip.Cursor = Cursors.SizeNWSE
        
AddHandler Me.lblSizingGrip.MouseMove, AddressOf Me.SizingGripMouseMove
        
AddHandler Me.lblSizingGrip.MouseDown, AddressOf Me.SizingGripMouseDown

        
Me.tvTreeView = New TreeView
        
Me.tvTreeView.BorderStyle = Windows.Forms.BorderStyle.None
        
AddHandler Me.tvTreeView.DoubleClick, AddressOf Me.TreeViewNodeSelect
        
Me.tvTreeView.Location = New Point(00)
        
AddHandler Me.tvTreeView.LostFocus, AddressOf Me.TreeViewLostFocus

        
Me.frmTreeView = New Form
        
Me.frmTreeView.FormBorderStyle = FormBorderStyle.None
        
Me.frmTreeView.StartPosition = FormStartPosition.Manual
        
Me.frmTreeView.ShowInTaskbar = False
        
Me.frmTreeView.BackColor = System.Drawing.SystemColors.Control

        
Me.pnlTree = New Panel
        
Me.pnlTree.BorderStyle = Windows.Forms.BorderStyle.FixedSingle
        
Me.pnlTree.BackColor = Color.White

        
Me.pnlTree.Controls.Add(Me.lblSizingGrip)
        
Me.pnlTree.Controls.Add(Me.tvTreeView)
        
Me.frmTreeView.Controls.Add(Me.pnlTree)
        
Me.pnlBack.Controls.AddRange(New Control() {btnSelect, tbSelectedValue})
        
Me.Controls.Add(Me.pnlBack)
    
End Sub


    
Private Sub RelocateGrip()
        
Me.lblSizingGrip.Top = Me.frmTreeView.Height - Me.lblSizingGrip.Height - 1
        
Me.lblSizingGrip.Left = Me.frmTreeView.Width - Me.lblSizingGrip.Width - 1
    
End Sub


    
Private Sub ToggleTreeView(ByVal sender As ObjectByVal e As EventArgs)
        
If Not Me.frmTreeView.Visible Then
            
Dim CBRect As Rectangle = Me.RectangleToScreen(Me.ClientRectangle)
            
Me.frmTreeView.Location = New Point(CBRect.X, CBRect.Y + Me.pnlBack.Height)

            
Me.frmTreeView.Show()
            
Me.frmTreeView.BringToFront()

            
Me.RelocateGrip()
        
Else
            
Me.frmTreeView.Hide()
        
End If
    
End Sub


    
Public Function ValidateTest() As Boolean
        
Dim ValidatorText As String = Me.text
        
Dim TNC As TreeNodeCollection = Me.tvTreeView.Nodes

        
For i As Integer = 0 To ValidatorText.Split(Me._branchSeparator.ToCharArray).Length
            
Dim NodeFound As Boolean = False
            
Dim NodeToFind As String = ValidatorText.Split(Me._branchSeparator.ToCharArray())(i)
            
For j As Integer = 0 To TNC.Count
                
If TNC(j).Text = NodeToFind Then
                    NodeFound 
= True
                    TNC 
= TNC(j).Nodes
                    
Exit For
                
End If
            
Next
            
If Not NodeFound Then Return False
        
Next
        
Return True
    
End Function



    
Private Sub SizingGripMouseMove(ByVal sender As ObjectByVal e As MouseEventArgs)
        
If e.Button = Windows.Forms.MouseButtons.Left Then
            
Dim TvWidth, TvHeight As Integer
            TvWidth 
= Windows.Forms.Cursor.Position.X - Me.frmTreeView.Location.X : TvWidth = TvWidth + Me.DragOffset.X
            TvHeight 
= Windows.Forms.Cursor.Position.Y - Me.frmTreeView.Location.Y : TvHeight = TvHeight + Me.DragOffset.Y

            
If TvWidth < 50 Then TvWidth = 50
            
If TvHeight < 50 Then TvHeight = 50

            
Me.frmTreeView.Size = New Size(TvWidth, TvHeight)
            
Me.pnlBack.Size = Me.frmTreeView.Size
            
Me.tvTreeView.Size = New Size(Me.frmTreeView.Size.Width - Me.lblSizingGrip.Width, Me.frmTreeView.Size.Height - Me.lblSizingGrip.Width)
            RelocateGrip()
        
End If
    
End Sub


    
Private Sub SizingGripMouseDown(ByVal sender As ObjectByVal e As MouseEventArgs)
        
If e.Button = Windows.Forms.MouseButtons.Left Then
            
Dim OffsetX As Integer = System.Math.Abs(Windows.Forms.Cursor.Position.X - Me.frmTreeView.RectangleToScreen(Me.frmTreeView.ClientRectangle).Right)
            
Dim OffsetY As Integer = System.Math.Abs(Windows.Forms.Cursor.Position.Y - Me.frmTreeView.RectangleToScreen(Me.frmTreeView.ClientRectangle).Bottom)

            
Me.DragOffset = New Point(OffsetX, OffsetY)
        
End If
    
End Sub


    
Private Sub TreeViewLostFocus(ByVal sender As ObjectByVal e As EventArgs)
        
If Not Me.btnSelect.RectangleToScreen(Me.btnSelect.ClientRectangle).Contains(Windows.Forms.Cursor.Position) Then Me.frmTreeView.Hide()
    
End Sub


    
Private Sub TreeViewNodeSelect(ByVal sender As ObjectByVal e As EventArgs)
        
If Me._absoluteChildrenSelectableOnly Then
            
Me.tbSelectedValue.Text = Me.tvTreeView.SelectedNode.FullPath.Replace(""Me._branchSeparator)
            
Me.ToggleTreeView(sender, Nothing)
        
Else
            
Me.tbSelectedValue.Text = Me.tvTreeView.SelectedNode.FullPath.Replace(""Me._branchSeparator)
            
Me.ToggleTreeView(sender, Nothing)
        
End If
    
End Sub


    
Private Sub InitializeComponent()
        
Me.Name = "ComboBoxTree"
        
Me._absoluteChildrenSelectableOnly = True
        
AddHandler Me.Layout, AddressOf Me.ComboBoxTree_Layout
    
End Sub


    
Private Sub ComboBoxTree_Layout(ByVal sender As ObjectByVal e As System.Windows.Forms.LayoutEventArgs)
        
Me.Height = Me.tbSelectedValue.Height + 8 : Me.Width = 400
        
Me.pnlBack.Size = New Size(Me.Width, Me.Height - 2)

        
Me.btnSelect.Size = New Size(16Me.Height - 6)
        
Me.btnSelect.Location = New Point(Me.Width - Me.btnSelect.Width - 40)

        
Me.tbSelectedValue.Location = New Point(22)
        
Me.tbSelectedValue.Width = Me.Width - Me.btnSelect.Width - 4

        
Me.frmTreeView.Size = New Size(Me.Width, Me.tvTreeView.Height)
        
Me.pnlTree.Size = Me.frmTreeView.Size
        
Me.tvTreeView.Width = Me.frmTreeView.Width - Me.lblSizingGrip.Width
        
Me.tvTreeView.Height = Me.frmTreeView.Height - Me.lblSizingGrip.Width
        
Me.RelocateGrip()

    
End Sub


    
Private Class LabelEx
        
Inherits Label

        
Public Sub New()
            
Me.SetStyle(ControlStyles.UserPaint Or ControlStyles.OptimizedDoubleBuffer Or ControlStyles.AllPaintingInWmPaint, True)
        
End Sub


        
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            
MyBase.OnPaint(e)
            System.Windows.Forms.ControlPaint.DrawSizeGrip(e.Graphics, Color.Black, 
10Me.Size.Width, Me.Size.Height)
        
End Sub

    
End Class


    
Private Class ButtonEx
        
Inherits Button

        
Dim state As ButtonState

        
Public Sub New()
            
Me.SetStyle(ControlStyles.UserMouse Or ControlStyles.OptimizedDoubleBuffer Or ControlStyles.AllPaintingInWmPaint, True)
        
End Sub


        
Protected Overrides Sub OnMouseDown(ByVal mevent As System.Windows.Forms.MouseEventArgs)
            
Me.state = ButtonState.Pushed
            
MyBase.OnMouseDown(mevent)
        
End Sub


        
Protected Overrides Sub OnMouseUp(ByVal mevent As System.Windows.Forms.MouseEventArgs)
            
Me.state = ButtonState.Normal
            
MyBase.OnMouseUp(mevent)
        
End Sub


        
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            
MyBase.OnPaint(e)
            System.Windows.Forms.ControlPaint.DrawComboButton(e.graphics, 
00Me.Width, Me.Height, state)
        
End Sub


    
End Class

End Class



 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值