ComponentOne Input for WinForms
Custom Drop-Down Form
Input for WinForms Tutorials > Custom Drop-Down Form

C1DropDownControl is a control derived from C1TextBox, so it supports all its formatting, validation, and other features. Like other two C1TextBox-derived controls, it also supports up/down (spin) and drop-down buttons. However, unlike those specialized controls, C1DropDownControl allows you to attach your own logic to the up/down buttons and your own drop-down form/editor to the drop-down button.

In this tutorial we will create a form that can be used to show a list of MRU (most recently used) values. Note that although we will use this form in only one control, the same form without modification can be used in any number of controls in your projects.

Note: Before opening Form1 at design time, you need to compile the tutorial project. Otherwise a "class not found" error will appear. This is because the drop-down form class needs to be compiled to become available in the DropDownFormClass property of a C1DropDownControl.

To create a custom drop-down form, complete the following steps:

  1. Create a new Windows Application project. Place a C1DropDownControl (C1DropDownControl1) on the form.

    Now, add a form derived from drop-down form to your project.

  2. From the Solution Explorer, right-click the project and select Add | New Item from the menu.
  3. In the Add New Item dialog box, select Windows Form from the list of Templates in the right pane.
  4. Then enter MRUDropDown.vb for Visual Basic (MRUDropDown.cs for C#) in the Name box and click Add.
  5. The next step is to replace the following class definition line(s) in the MRUDropDown form code. Select View | Code from the menu and replace the code below:

    To write code in Visual Basic

    Visual Basic
    Copy Code
    Public Class MRUDropDown
        Inherits System.Windows.Forms.Form
    

    To write code in C#

    C#
    Copy Code
    public partial class MRUDropDown : System.Windows.Forms.Form
    

    with:

    To write code in Visual Basic

    Visual Basic
    Copy Code
    Public Class MRUDropDown
        Inherits C1.Win.C1Input.DropDownForm
    

    To write code in C#

    C#
    Copy Code
    public partial class MRUDropDown : C1.Win.C1Input.DropDownForm
    
  6. From the Properties window, expand the Options property node of the MRUDropDown form.
  7. Set Option.Focusable to False and Option.AutoResize to True.

    The AutoResize option will make the width of the drop-down always equal the width of the control, and Focusable option set to False is needed because we do not want the drop-down form to take input focus. Instead, we want focus to remain in the control so the user can type in the control and select from the drop-down at the same time.

  8. Place a ListBox control (ListBox1) on the drop-down form. To make the list box occupy the whole drop-down area, set the following ListBox1 properties:
    Control Property Value
    ListBox1 Dock Fill
    IntegralHeight False
    BorderStyle None
  9. To make the form open automatically when the user starts typing in the control, use the OwnerControlTextChanged event, add the following event handler:

    To write code in Visual Basic

    Visual Basic
    Copy Code
    Private Sub MRUDropDown_OwnerControlTextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.OwnerControlTextChanged
        OwnerControl.OpenDropDown()
        ListBox1.SelectedIndex = listBox1.FindString(OwnerControl.Text)
    End Sub
    

    To write code in C#

    C#
    Copy Code
    private void MRUDropDown_OwnerControlTextChanged(object sender, System.EventArgs e)
    {
        OwnerControl.OpenDropDown();
        listBox1.SelectedIndex = listBox1.FindString(OwnerControl.Text);
    }
    

    The second line selects the list box item corresponding to the current control text, if such item already exists.

  10. To enable visual feedback while the user moves the mouse inside the list box, add the following event handler:

    To write code in Visual Basic

    Visual Basic
    Copy Code
    Private Sub ListBox1_MouseMove(ByVal sender As Object,ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseMove
        ListBox1.SelectedIndex = ListBox1.IndexFromPoint(e.X, e.Y)
    End Sub
    

    To write code in C#

    C#
    Copy Code
    private void listBox1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
    {
        listBox1.SelectedIndex = listBox1.IndexFromPoint(e.X, e.Y);
    }
    
  11. To enable the user to navigate the drop-down list box with the UP ARROW and DOWN ARROW keys and delete items with CTRL+DEL key, add the following event handler:

    To write code in Visual Basic

    Visual Basic
    Copy Code
    Private Sub MRUDropDown_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
        If e.Modifiers = Keys.None And e.KeyCode = Keys.Up Then
            If ListBox1.SelectedIndex > 0 Then
                ListBox1.SelectedIndex = listBox1.SelectedIndex - 1
                OwnerControl.Text = listBox1.Text
                OwnerControl.SelectAll()
            End If
            e.Handled = True
        End If
        If e.Modifiers = Keys.None And e.KeyCode = Keys.Down Then
            If ListBox1.SelectedIndex < listBox1.Items.Count - 1 Then
                ListBox1.SelectedIndex = listBox1.SelectedIndex + 1
                OwnerControl.Text = listBox1.Text
                OwnerControl.SelectAll()
            End If
            e.Handled = True
        End If
        If e.Modifiers = Keys.Control And e.KeyCode = Keys.Delete And ListBox1.SelectedIndex >= 0 Then
            ListBox1.Items.RemoveAt(listBox1.SelectedIndex)
            e.Handled = True
        End If
    End Sub
    

    To write code in C#

    C#
    Copy Code
    private void MRUDropDown_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
    {
        if (e.Modifiers == Keys.None && e.KeyCode == Keys.Up)
        {
            if (listBox1.SelectedIndex > 0)
            {
                listBox1.SelectedIndex--;
                OwnerControl.Text = listBox1.Text;
                OwnerControl.SelectAll();
            }
            e.Handled = true;
        }
        if (e.Modifiers == Keys.None && e.KeyCode == Keys.Down)
        {
            if (listBox1.SelectedIndex < listBox1.Items.Count - 1)
            {
                listBox1.SelectedIndex++;
                OwnerControl.Text = listBox1.Text;
                OwnerControl.SelectAll();
            }
            e.Handled = true;
        }
        if (e.Modifiers == Keys.Control && e.KeyCode == Keys.Delete && listBox1.SelectedIndex >= 0)
        {
            listBox1.Items.RemoveAt(listBox1.SelectedIndex);
            e.Handled = true;
        }
    }
    
  12. To select an item and close the drop-down form when the user clicks a list box item, add the following event handler:

    To write code in Visual Basic

    Visual Basic
    Copy Code
    Private Sub ListBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown
        ListBox1.SelectedIndex = listBox1.IndexFromPoint(e.X, e.Y)
        CloseDropDown(True)
    End Sub
    

    To write code in C#

    C#
    Copy Code
    private void listBox1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
    {
        listBox1.SelectedIndex = listBox1.IndexFromPoint(e.X, e.Y);
        CloseDropDown(true);
    }
    
  13. To make the drop-down form actually change the control text when it is closed after the user clicks an item, add the following event handler for the PostChanges event:

    To write code in Visual Basic

    Visual Basic
    Copy Code
    Private Sub MRUDropDown_PostChanges(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.PostChanges
        If ListBox1.SelectedIndex >= 0 Then
            OwnerControl.Value = listBox1.Text
        ElseIf ListBox1.FindStringExact(OwnerControl.Text) < 0 Then
            ListBox1.Items.Add(OwnerControl.Text)
        End If
    End Sub
    

    To write code in C#

    C#
    Copy Code
    private void MRUDropDown_PostChanges(object sender, System.EventArgs e)
    {
        if (listBox1.SelectedIndex >= 0)
            OwnerControl.Value = listBox1.Text;
        else if (listBox1.FindStringExact(OwnerControl.Text) < 0)
            listBox1.Items.Add(OwnerControl.Text);
    }
    

    Now the drop-down form is ready and we can use it in the C1DropDownControl1 in Form1.

  14. Open Form1, select C1DropDownContro1, go to the Properties window and select the DropDownFormClassName property. This property allows you to select a drop-down form-derived form from your project.
  15. Select <Project Name>.MRUDropDown from the combo box. This is all you need to attach the drop-down form to a control. If needed, you can attach this form to any number of controls the same way.

Run the program and observe the following: