代码如下:
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(9, 9)
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(0, 0)
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 Object, ByVal 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 Object, ByVal 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 Object, ByVal 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 Object, ByVal 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 Object, ByVal 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 Object, ByVal 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(16, Me.Height - 6)
Me.btnSelect.Location = New Point(Me.Width - Me.btnSelect.Width - 4, 0)
Me.tbSelectedValue.Location = New Point(2, 2)
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, 1, 0, Me.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, 0, 0, Me.Width, Me.Height, state)
End Sub
End Class
End Class
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(9, 9)
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(0, 0)
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 Object, ByVal 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 Object, ByVal 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 Object, ByVal 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 Object, ByVal 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 Object, ByVal 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 Object, ByVal 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(16, Me.Height - 6)
Me.btnSelect.Location = New Point(Me.Width - Me.btnSelect.Width - 4, 0)
Me.tbSelectedValue.Location = New Point(2, 2)
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, 1, 0, Me.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, 0, 0, Me.Width, Me.Height, state)
End Sub
End Class
End Class