Solved

Designing a simple drop down list box control from scratch

Posted on 2004-09-25
2
523 Views
Last Modified: 2012-06-27
Hi,
I’m trying to create a drop down control from scratch. I’m running into one problem so far: The actual drop down part of the box. So far I was thinking that making a separate form and managing its position would work. So I did that and it works great. The control would work for many applications the way it is. The problem is that I need to call dropdownform.show and this deactivates the form the actual drop down control lives on. I’ve attempted to put the code up in this message.

The question is how do I make a control that will ‘float’ over everything else (the window with the drop down selections in it) that does not deactivate the container control for the drop down.

Thanks for any help.


Control:
Public Class DropDownList
    Inherits System.Windows.Forms.UserControl

    'dropdownbutton
    Private mDropDownRegion As Drawing.Region

    'drop down form
    Dim WithEvents dropDownfrm As frmComboDrop
    Dim dropDownfrmHeight As Integer = 100
    Dim DropDownDirection As Integer = 1
    Dim Showingdropdownfrm As Boolean = False

#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.SetStyle(Windows.Forms.ControlStyles.DoubleBuffer Or Windows.Forms.ControlStyles.UserPaint Or Windows.Forms.ControlStyles.AllPaintingInWmPaint, True)
        Me.UpdateStyles()


        dropDownfrm = New frmComboDrop

    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.
    Friend WithEvents tmrShowForm As System.Windows.Forms.Timer
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.components = New System.ComponentModel.Container
        Me.tmrShowForm = New System.Windows.Forms.Timer(Me.components)
        '
        'tmrShowForm
        '
        Me.tmrShowForm.Interval = 25
        '
        'DropDownList
        '
        Me.BackColor = System.Drawing.SystemColors.Window
        Me.Name = "DropDownList"
        Me.Size = New System.Drawing.Size(208, 20)

    End Sub

#End Region

    Private ReadOnly Property ClickBoxSize() As Integer
        Get
            Return Me.Size.Height
        End Get
    End Property
    <ComponentModel.Browsable(False)> Public ReadOnly Property Items() As ArrayList
        Get
            Return dropDownfrm.Items
        End Get
    End Property


    Private Sub DropDownList_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Resize
        Me.Size = New Drawing.Size(Me.Size.Width, ClickBoxSize)
        Me.Invalidate()
    End Sub
    Private Sub DropDownList_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
        Dim DropDownButtonRect As New Drawing.Rectangle(Me.Size.Width - ClickBoxSize - 1, 0, ClickBoxSize, ClickBoxSize - 1)
        Dim TextBoxAreaRect As New Drawing.Rectangle(0, 0, Me.Size.Width - DropDownButtonRect.Width, Me.Size.Height - 1)
        Dim SymbolFont As New Drawing.Font("Marlett", 16, Drawing.FontStyle.Regular, Drawing.GraphicsUnit.Pixel)
        Dim DownArrowSize As Drawing.Size = e.Graphics.MeasureString("6", SymbolFont).ToSize


        'draw the text box stuff
        e.Graphics.FillRectangle(Drawing.SystemBrushes.Window, TextBoxAreaRect)

        'text in text box area
        Dim TextSize As Drawing.Size = e.Graphics.MeasureString(Me.Text, Me.Font).ToSize
        Dim TextPoint As New Drawing.Point(0, CInt(TextBoxAreaRect.Height / 2 - TextSize.Height / 2))
        e.Graphics.DrawString(Me.Text, Me.Font, Drawing.SystemBrushes.ControlText, TextPoint.X, TextPoint.Y)


        'draw button
        e.Graphics.FillRectangle(Drawing.SystemBrushes.Control, DropDownButtonRect)
        'draw button text
        Dim ButtonTextPoint As New Drawing.Point(DropDownButtonRect.X + CInt(DropDownButtonRect.Width / 2 - DownArrowSize.Width / 2), DropDownButtonRect.Y + CInt(DropDownButtonRect.Height / 2 - DownArrowSize.Height / 2))
        e.Graphics.DrawString("6", SymbolFont, Drawing.SystemBrushes.ControlText, ButtonTextPoint.X, ButtonTextPoint.Y)
        'button border
        e.Graphics.DrawRectangle(Drawing.SystemPens.ControlText, DropDownButtonRect)









        If Not mDropDownRegion Is Nothing Then
            mDropDownRegion.Dispose()
        End If
        mDropDownRegion = New Drawing.Region(DropDownButtonRect)
    End Sub
    Private Sub DropDownList_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown
        If Not mDropDownRegion Is Nothing Then
            If mDropDownRegion.IsVisible(e.X, e.Y) Then
                Dim button As New Windows.Forms.Button
                button.Location = New Drawing.Point(10, 10)
                button.Show()
                'ShowDropDown()
            End If
        End If
    End Sub


    Private Sub ShowDropDown()
        If Showingdropdownfrm = False Then
            dropDownfrm.Size = New Drawing.Size(Me.Size.Width, 10)
            dropDownfrm.Location = Me.PointToScreen(New Drawing.Point(0, Me.Height))
            dropDownfrm.TopMost = True
            dropDownfrm.Show()
            tmrShowForm.Enabled = True
            Showingdropdownfrm = True
            DropDownDirection = 1
            'dropDownfrm.Focus()
        End If
    End Sub
    Private Sub dropDownfrm_HideMeEvent(ByVal sender As Object, ByVal e As System.EventArgs) Handles dropDownfrm.HideMeEvent
        DropDownDirection = -1
        tmrShowForm.Enabled = True
    End Sub

    Private Sub tmrShowForm_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrShowForm.Tick
        If Showingdropdownfrm Then
            Dim NewHeight As Integer = dropDownfrm.Size.Height
            NewHeight += DropDownDirection * Convert.ToInt32(dropDownfrmHeight / 3)
            If NewHeight > dropDownfrmHeight Then
                NewHeight = dropDownfrmHeight
                tmrShowForm.Enabled = False
            End If
            If NewHeight < 0 Then
                dropDownfrm.Hide()
                Showingdropdownfrm = False
                tmrShowForm.Enabled = False
                Exit Sub
            End If


            dropDownfrm.Size = New Drawing.Size(Me.Size.Width, NewHeight)
            dropDownfrm.Location = Me.PointToScreen(New Drawing.Point(0, Me.Height))

        End If
    End Sub

    Private Sub dropDownfrm_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles dropDownfrm.TextChanged
        Me.Text = DirectCast(sender, frmComboDrop).Text
    End Sub
    Private Sub DropDownList_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.TextChanged
        Me.Invalidate()
    End Sub

End Class

'probably put this in another file?
Friend Class frmComboDrop
    Inherits System.Windows.Forms.Form

    Public Event HideMeEvent(ByVal sender As Object, ByVal e As EventArgs)

    Private mItems As New ArrayList


#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.SetStyle(Windows.Forms.ControlStyles.Selectable, False)
        Me.UpdateStyles()

    End Sub

    'Form 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.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        '
        'frmComboDrop
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.AutoScroll = True
        Me.BackColor = System.Drawing.SystemColors.Window
        Me.ClientSize = New System.Drawing.Size(164, 100)
        Me.ControlBox = False
        Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None
        Me.Name = "frmComboDrop"
        Me.ShowInTaskbar = False
        Me.StartPosition = System.Windows.Forms.FormStartPosition.Manual

    End Sub

#End Region

    Public ReadOnly Property Items() As ArrayList
        Get
            Return mItems
        End Get
    End Property

    Private Sub Item_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        Me.Text = DirectCast(sender, Windows.Forms.LinkLabel).Text
        RaiseEvent HideMeEvent(Me, New EventArgs)
    End Sub

    Private Sub frmComboDrop_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.GotFocus
        'show all the data
        Me.Controls.Clear()
        For Each itm As Object In Items
            Dim lnk As New Windows.Forms.LinkLabel
            lnk.Text = itm.ToString
            lnk.AutoSize = True
            lnk.LinkBehavior = Windows.Forms.LinkBehavior.HoverUnderline
            AddHandler lnk.Click, AddressOf Item_Click

            lnk.Location = New Drawing.Point(0, Me.Controls.Count * (lnk.Size.Height + 1))
            Me.Controls.Add(lnk)
        Next
    End Sub

    Private Sub frmComboDrop_Deactivate(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Deactivate
        RaiseEvent HideMeEvent(Me, New EventArgs)
    End Sub

End Class
0
Comment
Question by:xersoft
2 Comments
 
LVL 5

Author Comment

by:xersoft
Comment Utility
I'm very sorry there is a mistake in the above code please replace the following with what follows that

'CLASS: DropDownList


'bad code
Private Sub DropDownList_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown
        If Not mDropDownRegion Is Nothing Then
            If mDropDownRegion.IsVisible(e.X, e.Y) Then
                Dim button As New Windows.Forms.Button
                button.Location = New Drawing.Point(10, 10)
                button.Show()
                'ShowDropDown()
            End If
        End If
    End Sub



'good code
    Private Sub DropDownList_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown
        If Not mDropDownRegion Is Nothing Then
            If mDropDownRegion.IsVisible(e.X, e.Y) Then
                ShowDropDown()
            End If
        End If
    End Sub
0
 
LVL 2

Accepted Solution

by:
GohdanTheMoblin earned 125 total points
Comment Utility
http://www.vbaccelerator.com/home/NET/Code/Controls/Popup_Windows/Popup_Windows/article.asp

The above article is in C#, but covers the theory and code necessary to use a form as a popup window in the way you want.  
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

This article explains how to create and use a custom WaterMark textbox class.  The custom WaterMark textbox class allows you to set the WaterMark Background Color and WaterMark text at design time.   IMAGE OF WATERMARKS STEPS Create VB …
Introduction When many people think of the WebBrowser (http://msdn.microsoft.com/en-us/library/2te2y1x6%28v=VS.85%29.aspx) control, they immediately think of a control which allows the viewing and navigation of web pages. While this is true, it's a…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now