Imports System.ComponentModel Imports System.Runtime.InteropServices Imports System.Windows.Forms Imports System.Drawing Namespace Controls Friend Class ComboBoxTree_ComboBox Inherits System.Windows.Forms.ComboBox #Region " Windows Form Designer generated code " Public Sub New() MyBase.New() 'This call is required by the Windows Form Designer. InitializeComponent() 'Add any initialization after the InitializeComponent() call Me.DrawMode = DrawMode.OwnerDrawFixed End Sub 'UserControl overrides dispose to clean up the component list. Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then If Not (components Is Nothing) Then components.Dispose() End If End If MyBase.Dispose(disposing) End Sub 'Required by the Windows Form Designer Private components As System.ComponentModel.IContainer 'NOTE: The following procedure is required by the Windows Form Designer 'It can be modified using the Windows Form Designer. 'Do not modify it using the code editor. Private Sub InitializeComponent() components = New System.ComponentModel.Container End Sub #End Region Public Event BeforeSelect(ByVal Node As TreeNode, ByRef Cancel As Boolean) Public Event AfterSelect() Public Shadows Event DropDown() Public Shadows Event CloseUp() Friend WithEvents TreeView As New ComboBoxTree_TreeView Private IsDroppingDown As Boolean = False Private FocusOnMouseLeave As Boolean = False Private FocusOnVisibleChanged As Boolean = False Private Declare Function ShowWindow Lib "user32" (ByVal hWnd As IntPtr, ByVal nCmdShow As Integer) As Integer Private Const SW_HIDE As Integer = 0 Private Const WM_CTLCOLORLISTBOX As Int32 = &H134 'Private Const CBN_DROPDOWN = 7 'Private Const CBN_CLOSEUP = 8 'Private Const WM_USER As Integer = &H400 'Private Const WM_COMMAND As Integer = &H111 'Private Const OCM__BASE As Integer = WM_USER + &H1C00 'Private Const OCM_COMMAND As Integer = OCM__BASE + WM_COMMAND 'Private Function HiWord(ByVal Value As Integer) As Short ' Return CShort(New System.Drawing.Point(value).Y) 'End Function #Region " ComboBox Properties and Methods " Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) ' Hide the standard dropdown window of the combobox control If m.Msg = WM_CTLCOLORLISTBOX Then Call ShowWindow(m.LParam, SW_HIDE) 'ElseIf m.Msg = OCM_COMMAND Then ' Select Case HiWord(m.WParam.ToInt32) ' Case CBN_CLOSEUP ' Case CBN_DROPDOWN ' End Select End If MyBase.WndProc(m) End Sub Public Shadows Property SelectedItem() As TreeNode Get Dim CurrentSelection As TreeNodeEx = MyBase.SelectedItem If CurrentSelection Is Nothing Then Return Nothing Else Return CurrentSelection.TreeNode End If End Get Set(ByVal Value As TreeNode) If Value Is Nothing Then Dim Cancel As Boolean = False RaiseEvent BeforeSelect(Nothing, Cancel) If Cancel Then Exit Property Me.TreeView.SelectedNode = Nothing Me.Items.Clear() RaiseEvent AfterSelect() Else Me.TreeView.SelectedNode = Value End If End Set End Property Public Shadows Property SelectedValue() As Object Get Dim currentselection As TreeNodeEx = MyBase.SelectedItem If currentselection Is Nothing Then Return Nothing Else Return currentselection.TreeNode.Tag End If End Get Set(ByVal value As Object) End Set End Property Public Shadows Property DroppedDown() As Boolean Get Return Me.TreeView.Visible End Get Set(ByVal Value As Boolean) If IsDroppingDown Then Exit Property IsDroppingDown = True If Value Then If Not Me.TreeView.Visible Then Me.TreeView.BringToFront() Me.TreeView.Show() Me.Focus() Me.TreeView.Focus() RaiseEvent DropDown() End If ElseIf Me.TreeView.Visible Then Me.TreeView.Hide() RaiseEvent CloseUp() End If IsDroppingDown = False End Set End Property Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs) If e.Index = -1 Then Return ' Draw only the combo edit box If (e.State And DrawItemState.ComboBoxEdit) <> DrawItemState.ComboBoxEdit Then Return Dim ComboBoxSelection As TreeNodeEx Try ComboBoxSelection = CType(Me.Items(e.Index), TreeNodeEx) e.DrawFocusRectangle() e.DrawBackground() Dim TextLeft As Integer = e.Bounds.Left If Not Me.TreeView.ImageList Is Nothing Then Dim ImageIndex As Integer = ComboBoxSelection.TreeNode.SelectedImageIndex If ImageIndex < 0 Then ImageIndex = Me.TreeView.SelectedImageIndex If ImageIndex >= 0 Then Dim IconRectangle As Rectangle If Me.TreeView.ImageList.ImageSize.Height > Me.ItemHeight Then IconRectangle = New Rectangle(e.Bounds.Left + 2, e.Bounds.Top, Me.ItemHeight, Me.ItemHeight) Else IconRectangle = New Rectangle(New Point(e.Bounds.Left + 2, e.Bounds.Top), Me.TreeView.ImageList.ImageSize) End If Me.TreeView.ImageList.Draw(e.Graphics, IconRectangle.Left, IconRectangle.Top, IconRectangle.Width, IconRectangle.Height, ImageIndex) TextLeft = TextLeft + IconRectangle.Width + 2 IconRectangle = Nothing End If End If e.Graphics.DrawString(ComboBoxSelection.TreeNode.Text, Me.Font, New SolidBrush(e.ForeColor), TextLeft, e.Bounds.Top + 2) Catch ex As Exception 'Throw ex Finally ComboBoxSelection = Nothing MyBase.OnDrawItem(e) End Try End Sub Protected Overrides Sub OnDropDown(ByVal e As System.EventArgs) If Not Me.DroppedDown Then Me.DroppedDown = True End Sub Protected Overrides Sub OnCreateControl() Me.TreeView.Visible = False Me.TreeView.Height = 194 Me.TreeView.ImageIndex = 0 Me.TreeView.SelectedImageIndex = 1 Me.TreeView.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle Me.TreeView.TabIndex = Me.TabIndex Me.TreeView.TabStop = False Me.TreeView.HideSelection = False End Sub Protected Overrides Sub OnKeyDown(ByVal e As System.Windows.Forms.KeyEventArgs) If ((e.KeyCode = Keys.Up) OrElse (e.KeyCode = Keys.Down)) AndAlso (e.Modifiers = Keys.Alt) Then e.Handled = True Me.DroppedDown = True End If End Sub Protected Overrides Sub OnClick(ByVal e As System.EventArgs) If Me.DroppedDown Then Me.DroppedDown = False Me.Focus() Me.FindForm.Focus() Me.Focus() End If End Sub #End Region #Region " TreeView Methods " Private Sub TreeView_BeforeSelect(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles TreeView.BeforeSelect RaiseEvent BeforeSelect(e.Node, e.Cancel) End Sub Private Sub TreeView_AfterSelect(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView.AfterSelect Me.Items.Clear() Me.Items.Add(New TreeNodeEx(e.Node)) Me.SelectedIndex = 0 If e.Action = TreeViewAction.ByMouse Then FocusOnMouseLeave = True Me.DroppedDown = False End If RaiseEvent AfterSelect() End Sub Private Sub TreeView_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles TreeView.Leave If Not Me.Focused Then Me.DroppedDown = False End Sub Private Sub TreeView_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles TreeView.MouseLeave If FocusOnMouseLeave Then FocusOnMouseLeave = False Me.Focus() Me.FindForm.Focus() Me.Focus() End If End Sub Private Sub TreeView_VisibleChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TreeView.VisibleChanged If FocusOnVisibleChanged Then FocusOnVisibleChanged = False Me.Focus() Me.FindForm.Focus() Me.Focus() End If End Sub Private Sub TreeView_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TreeView.KeyPress If (e.KeyChar = ChrW(System.Windows.Forms.Keys.Enter)) OrElse (e.KeyChar = ChrW(System.Windows.Forms.Keys.Escape)) Then e.Handled = True FocusOnVisibleChanged = True Me.DroppedDown = False End If End Sub Private Sub TreeView_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TreeView.KeyDown If ((e.KeyCode = Keys.Up) OrElse (e.KeyCode = Keys.Down)) AndAlso (e.Modifiers = Keys.Alt) Then e.Handled = True FocusOnVisibleChanged = True Me.DroppedDown = False End If End Sub #End Region Private Class TreeNodeEx Public TreeNode As TreeNode Public Sub New(ByVal Node As TreeNode) Me.TreeNode = Node End Sub Public Overrides Function ToString() As String Return Me.TreeNode.Text End Function End Class End Class End Namespace