Home

Windows Controls: The Combo Box

 

Introduction to Combo Boxes

 

Description

A combo box is a list of items that the user can select from. A combo box is usually made of a list of strings. A combo box saves space by using just as much room as a text box control. To show that it is holding a list, a combo box displays a down-pointing arrow on the right side of its text box. In the following screenshot, the Font Effects property page of the Character dialog box of OpenOffice.org presents the Font Color, the Effects, the Relief, the Overlining, the Strikethrough, and the Underlining combo boxes:

The Font Effects tab of the Character dialog box displays various combo boxes

Because a combo box does not (permanently) display its list, to show its content, the user can click the arrow button. Here is an example:

ApplicationPractical Learning: Introducing Combo Boxes

  1. Start Microsoft Visual Studio
  2. To create a new application, on the main menu, click File -> New Project...
  3. In the middle list, click Windows Forms Application
  4. Set the Name to ClarksvilleIceCream3
  5. From the Menus & Toolbars section of the Toolbox, click MenuStrip and click the form
  6. Under the form, right-click menuStrip1 and click Insert Standard Items
  7. In the Common Controls section of the Toolbox, click ToolTip ToolTip and click the form

Creating a Combo Box

To support combo boxes, the .NET Framework provides a class named ComboBox. At design time, to add a combo box to your application, from the Common Controls section of the Toolbox, you can click the ComboBox button ComboBox and click the form or a container.

The ComboBox class is derived from the ListControl class. To programmatically create a combo box, create a handle to ComboBox, allocate memory for it using the gcnew operator and add it to the Controls collection of its container. Here is an example:

#include <windows.h>

#using <System.dll>
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>

using namespace System;
using namespace System::Drawing;
using namespace System::Windows::Forms;

public ref class CExercise : public Form
{
private:
    Label ^ lblTitle;
    ComboBox ^ cbxAcademicDisciplines;

public:
    CExercise()
    {
	InitializeComponent();
    }

private:
    void InitializeComponent()
    {
        lblTitle = gcnew Label;
        lblTitle->Text = "Academic Disciplines";
        lblTitle->Location =  Point(12, 12);
        lblTitle->AutoSize = true;
        Controls->Add(lblTitle);

        cbxAcademicDisciplines = gcnew ComboBox;
        cbxAcademicDisciplines->Location =  Point(12, 32);

        Controls->Add(cbxAcademicDisciplines);
    }
};

int APIENTRY WinMain(HINSTANCE hInstance,
		     HINSTANCE hPrevInstance,
		     LPSTR lpCmdLine,
		     int nCmdShow)
{
    Application::Run(gcnew CExercise);

    return 0;
}

This would produce:

Combo Box

ApplicationPractical Learning: Creating Combo Boxes

  • Design the form as follows:
     
    Clarksville Ice Cream: Form Design
    Control Name Text TextAlign ToolTip On ToolTip1
    GroupBox GroupBox grpIceCream      
    Label Label   Order &Date:    
    TextBox ListBox txtOrderDate     Enter a value for a date (MM/DD/YYYY)
    Label Label   Order &Time:    
    TextBox ListBox txtOrderTime     Enter a value for a time (23:59)
    Label Label   &Flavor:    
    ComboBox ComboBox cboFlavors     Click the arrow to display a list, then select a flavor from the list
    Label Label   &Container:    
    ComboBox ComboBox cboContainers     Click to display the list of containers and select one
    Label Label   &Ingredient:    
    ComboBox ComboBox cboIngredients     Display the list of ingredients and select the customer's choice
    Label Label   &Scoops:    
    TextBox ListBox txtScoops 1 Right Enter the number of scoops (1, 2, or 3) to fill the container
    Button Button btnCalculate C&alculate    
    Label Label   &Order Total:    
    TextBox ListBox txtOrderTotal 0.00 Right This displays the total amount of this order

Characteristics of a Combo Box

 

Introduction

Like all visual controls, a combo box shares all the basic characteristics of other graphic control: the name, the location, the size, the ability to be enabled or disabled, the ability to hide or show it, the ability to dock or anchor, etc.

Creating the List of Items

Probably the most important aspect of a combo box is the list of items it holds. Like all other list-based controls, the list of a combo box is held by the Items property of the ComboBox class. To visually create the list of items, you can use the String Collection Editor.

The Items property of the ComboBox class is created from the nested ObjectCollection class. To programmatically create a list of items, you can (continuously) call the ObjectCollection::Add() member function. Here is an example:

public ref class CExercise : public Form
{
private:
    Label ^ lblTitle;
    ComboBox ^ cbxAcademicDisciplines;

public:
    CExercise()
    {
	InitializeComponent();
    }

private:
    void InitializeComponent()
    {
        lblTitle = gcnew Label;
        lblTitle->Text = "Academic Disciplines";
        lblTitle->Location =  Point(12, 12);
        lblTitle->AutoSize = true;
        Controls->Add(lblTitle);

        cbxAcademicDisciplines = gcnew ComboBox;
        cbxAcademicDisciplines->Location =  Point(12, 32);
        cbxAcademicDisciplines->Items->Add("Natural sciences");
        cbxAcademicDisciplines->Items->Add("Mathematics and Computer sciences");
        cbxAcademicDisciplines->Items->Add("Social sciences");
        cbxAcademicDisciplines->Items->Add("Humanities");
        cbxAcademicDisciplines->Items->Add("Professions and Applied sciences");

        Controls->Add(cbxAcademicDisciplines);
    }
};

This would produce:

Combo Box

To add an array of items, you can call the AddRange() member function. Here is an example:

void InitializeComponent()
{
    lblTitle = gcnew Label;
    lblTitle->Text = "Academic Disciplines";
    lblTitle->Location =  Point(12, 12);
    lblTitle->AutoSize = true;
    Controls->Add(lblTitle);

    cbxAcademicDisciplines = gcnew ComboBox;
    cbxAcademicDisciplines->Location =  Point(12, 32);

    array<String ^> ^ disciplines = gcnew array<String ^>(3);

    cbxAcademicDisciplines->Items->Add("Natural sciences");
    cbxAcademicDisciplines->Items->Add("Mathematics and Computer sciences");
    cbxAcademicDisciplines->Items->Add("Social sciences");
    cbxAcademicDisciplines->Items->Add("Humanities");
    cbxAcademicDisciplines->Items->Add("Professions and Applied sciences");

    disciplines[0] = "Business Administration";
    disciplines[1] = "Criminal Justice";
    disciplines[2] = "Art History";
    cbxAcademicDisciplines->Items->AddRange(disciplines);

    Controls->Add(cbxAcademicDisciplines);
}

To insert an item somewhere inside the list, you can call the Insert() member function.

If you want the list of items to be sorted, you can change the value of the Sorted property in the Properties window from False (the default) to True. To sort a list programmatically, you can assign a true value to the Sorted property. You can un-sort the list by changing the value of the Sorted property. This property works exactly like its equivalent in the ListBox control.

ApplicationPractical Learning: Adding Items to a Combo Box

  1. To create a list of items, on the form, right-click the Flavor combo box (the combo box on the right side of the Flavor label) and click Edit Items...
  2. In the String Collection Editor, type Other and press Enter
  3. Complete the list with the following items:
     
    Other
    Vanilla
    Cherry Coke
    Butter Pecan
    Chunky Butter
    Chocolate Chip
    Caramel Au Lait
    Cream of Cocoa
    Chocolate Cookie
    Organic Strawberry
    Chocolate Brownies

     
    String Collection Editor
  4. Click OK
  5. Click the Container combo box
  6. Under the Properties window, click Edit Items...
  7. Type the following values:
     
    Cup
    Bowl
    Cone
    Other
  8. Click OK
  9. Click the Ingredient combo box
  10. In the Properties window, on the right side of Items, click (Collection) and click its browse button
  11. Type the following values:
     
    None
    M & M
    Cookies
    Peanuts
    Mixed Nuts
  12. Click OK
  13. On the main menu, click File -> Close Solution
  14. When asked whether you want to save, click Save and click Save
  15. To start a new application, on the main menu, click File -> New Project...
  16. In the middle list, click Windows Forms Application
  17. Set the Name to CPAP1
  18. Click OK
  19. Design the form as follows:
     
    College Park Auto Parts - Form Design
    Control Text Name
    GroupBox GroupBox Part Selection  
    Label Label Year  
    Label Label Make  
    Label Label Model  
    Label Label Category  
    ComboBox ComboBox   cbxCarYears
    ComboBox ComboBox   cbxMakes
    ComboBox ComboBox   cbxModels
    ComboBox ComboBox   cbxCategories
    GroupBox GroupBox Available Parts  
    DataGridView Data Grid View   dgvAvailableParts
    Button Button Close btnClose
  20. To create a list of items using the Add() member function, double-click an unoccupied area of the form and implement its Load event as follows:
    System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e)
    {
        for(int i = DateTime::Now.Year; i >= 1960; i--)
            cbxYears->Items->Add(i);
    }
  21. To execute the application to test it, press F5
  22. Close the form and return to your programming environment

Selecting an Item

To select an item from the list, the user can click it. To programmatically select an item, you can assign a string to the Text property of a DropDown or a Simple combo box. Probably the best way to select an item is to specify its index. The items of a combo box are stored in a zero-based list. To select an item, you can assign its position to the SelectedIndex property. In the same way, to find out what item is selected, you can get the value of the SelectedIndex property.

Instead of using the index of an item, to select an item using its identity or name, you can use the SelectedItem property. To select an item by its name, assign it to the SelectedItem property.

ApplicationPractical Learning: Selecting an Item

  1. On the main menu, click Project -> Add Class...
  2. In the middle list, make sure C++ Class is selected. Click Add
  3. Set the name to CPartDescription
  4. Click Finish
  5. Change the header file as follows:
    #pragma once
    using namespace System;
    
    public ref class CPartDescription
    {
    private:
        long ID;
        int yr;
        String ^ mk;
        String ^ mdl;
        String ^ cat;
        String ^ name;
        double price;
    
    public:
        CPartDescription(void);
        CPartDescription(long code,
                         int year,
                         String ^ make,
                         String ^ model,
                         String ^ type,
                         String ^ desc,
                         double uPrice);
    
        property long PartNumber
        {
            long get() { return ID; }
            void set(long value) { ID = value; }
        }
    
        property int CarYear
        {
            int get() { return yr; }
            void set(int value) { yr = value; }
        }
    
        property String ^ Make
        {
            String ^ get() { return mk; }
            void set(String ^ value) { mk = value; }
        }
    
        property String ^ Model
        {
            String ^ get() { return mdl; }
            void set(String ^ value) { mdl = value; }
        }
    
        property String ^ Category
        {
            String ^ get() { return cat ; }
            void set(String ^ value) { cat = value; }
        }
    
        property String ^ PartName
        {
            String ^ get() { return name; }
            void set(String ^ value) { name = value; }
        }
    
        property double UnitPrice
        {
            double get() { return (price < 0) ? 0.00 : price; }
            void set(double value) { price = value; }
        }
    
        virtual String ^ ToString() override;
    };
  6. Change the source file as follows:
    #include "StdAfx.h"
    #include "PartDescription.h"
    
    CPartDescription::CPartDescription(void)
    {
        ID = 0;
        yr = 1960;
        mk = "";
        mdl = "";
        cat = "";
        name = "";
        price = 0.00;
    }
    
    CPartDescription::CPartDescription(long code, int year, String ^ make,
    				   String ^ model, String ^ type,
    				   String ^ desc, double uPrice)
    {
        ID    = code;
        yr    = year;
        mk    = make;
        mdl   = model;
        cat   = type;
        name  = desc;
        price = uPrice;
    }
    
    String ^ CPartDescription::ToString()
    {
        return PartNumber + " " +
               CarYear.ToString() + " " +
               Make + " " +
               Model + " " +
               Category + " " +
               PartName + " " +
               UnitPrice;
    }
  7. In the Class View, right-click CollectParkAutoParts1 -> Add -> Class...
  8. In the middle list, make sure C++ Class is selected.
    Click Add
  9. Set the name to CPartSelected
  10. Click Finish
  11. Change the header file as follows:
    #pragma once
    using namespace System;
    
    public ref class CPartSelected
    {
    private:
        long ID;
        String ^ name;
        double price;
    
    public:
        CPartSelected(void);
        CPartSelected(long code, String ^ desc, double uPrice);
    
        property long PartNumber
        {
            long get() { return ID; }
            void set(long value) { ID = value; }
        }
    
        property String ^ PartName
        {
            String ^ get() { return name; }
            void set(String ^ value) { name = value; }
        }
    
        property double UnitPrice
        {
            double get() { return (price < 0) ? 0.00 : price; }
            void set(double value) { price = value; }
        }
    
        virtual String ^ ToString() override;
    };
  12. Change the source file as follows:
    #include "StdAfx.h"
    #include "PartSelected.h"
    
    CPartSelected::CPartSelected(void)
    {
        ID = 0;
        name = "Unknown";
        price = 0.00;
    }
    
    CPartSelected::CPartSelected(long code, String ^ desc, double uPrice)
    {
        ID = code;
        name = desc;
        price = uPrice;
    }
    
    String ^ CPartSelected::ToString()
    {
        return PartNumber + " " + PartName + " " + UnitPrice;
    }
  13. Access the Form1.h header file and change the top of the file as follows:
    #pragma once
    
    #include "PartDescription.h"
    #include "PartSelected.h"
    
    namespace CPAP1 {
    
        using namespace System;
        using namespace System::ComponentModel;
        using namespace System::Collections;
        using namespace System::Collections::Generic;
        using namespace System::Windows::Forms;
        using namespace System::Data;
        using namespace System::Drawing;
    
        /// <summary>
        /// Summary for Form1
        /// </summary>
        public ref class Form1 : public System::Windows::Forms::Form
        {
            List<CPartDescription ^> ^ lstParts;
            BindingSource ^ bsPartsSelected;
  14. Scroll down and change the Load event as follows:
    System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e)
    {
        lstParts = gcnew List<CPartDescription ^>;
        bsPartsSelected = gcnew BindingSource;
    
    	for(int i = DateTime::Now.Year; i >= 1960; i--)
            cbxYears->Items->Add(i);
    
    	CPartDescription ^ part = nullptr;
                
        part = gcnew CPartDescription(447093, 2002, "Ford",
                    "Escort SE L4 2.0", "Engine Electrical",
                    "Alternator 75amp  Remanufactured; w/ 75 Amp",
                    205.05);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(203815, 2006, "Dodge",
                    "Caravan SE L4 2.4", "Cooling System",
                    "Radiator Cap", 6.65);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(293047, 2000, "Toyota",
                    "RAV4 2WD/4-DOOR", "Cooling System",
                    "Thermostat Gasket", 4.95);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(990468, 2002, "Honda",
                    "Civic 1.7 EX 4DR", "Exhaust",
                    "Bolt & Spring Kit (Manifold outlet, Muffler Inlet)",
                    85.75);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(304158, 1996, "Buick",
                    "Regal Custom V6 3.8", "Fuel Injection",
                    "Fuel Injector", 82.75);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(807245, 2004, "Acura",
                    "MDX 3.5 4WD", "Driveshaft & Axle",
                    "CV Boot Clamp 7 x 750mm; 1 Large + 1 Small Clamp", 1.60);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(203485, 2001, "Ford",
                   "Taurus LX V6 3.0", "Fuel Injection",
                    "Oxygen Sensor OE Style 4Wire; Front; 2 Required", 52.65);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(248759, 1999, "Jeep",
                    "Wrangler Sahara", "Air Intake",
                    "Air Filter AirSoft Panel", 7.95);
        lstParts->Add(part);
    
         part = gcnew CPartDescription(202848, 1998, "Honda",
                    "Accord 2.3 LX 4DR", "Air Intake",
                    "Air Filter", 12.55);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(932759, 2006, "Kia",
                    "Rio 1.6DOHC16V 4-DR", "Cooling System",
                    "Thermostat", 14.45);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(304975, 2000, "Honda",
                    "Civic 1.6 EX 4DR", "Suspension",
                    "Ball Joint; Front Lower; 2 per car", 40.55);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(208450, 2003, "Chevrolet",
                    "Monte Carlo LS V6 3.4", "Fuel Injection",
                    "Oxygen Sensor OE connector; Rear", 65.55);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(209480, 2002, "Ford",
                    "Focus SE DOHC L4 2.0", "Steering",
                    "Steering Rack Remanufactured", 170.85);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(203495, 2004, "Honda",
                    "Civic 1.7 EX 4DR", "Climate Control",
                    "A/C Clutch; OE compressor = Sanden", 184.95);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(203480, 2007, "Toyota",
                    "Corolla", "Air Intake",
                    "Air Filter", 12.65);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(109379, 2005, "Volvo",
                    "S40 2.5L T5 AWD", "Fuel Delivery",
                    "Fuel Filter; Early Design; Outer Diameter = 55mm", 30.95);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(935794, 2002, "Ford",
                    "Escape XLS 4WD", "Brake",
                    "Brake Caliper Remanufactured; Front Right",
                    65.55);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(203485, 2006, "BMW",
                    "325i", "Climate Control",
                    "AC High Pressure Side Switch", 49.95);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(204875, 1996, "Chevrolet",
                    "Monte Carlo Z34 V6 3.4", "Fuel Delivery",
                    "Fuel Filter", 8.05);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(937485, 2007, "Toyota",
                    "Camry V6", "Air Intake", "Air Filter", 12.95);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(294759, 2001, "Ford",
                    "Escape XLT 4WD", "Air Intake",
                    "Air Filter Panel", 7.25);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(297495, 2003, "Honda",
                    "Civic 1.7 EX 4DR", "Brake",
                    "Brake Caliper Reman; w/ ProAct Pads; Front Right",
                    82.55);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(794735, 2006, "BMW",
                    "325i", "Climate Control",
                    "Cabin Air/Pollen Filter; With Activated Carbon",
                    28.05);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(937485, 2007, "Toyota",
                    "Corolla", "Body Electrical",
                    "Halogen  SilverStar; 12V 65W; inner-high beam",
                    22.85);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(492745, 2005, "Ford",
                    "Focus ZX3 L4 2.0", "Air Intake",
                    "Fuel Injection Perf Kit", 342.95);
        lstParts->Add(part);
    
        part = gcnew CPartDescription(937005, 2004, "Acura",
                    "MDX 3.5 4WD", "Driveshaft & Axle",
                    "CV Boot Clamp 7 x 750mm; For Large End of Boot; inner boot", 1.60);
        lstParts->Add(part);
    
                part = gcnew CPartDescription(293749, 2004, "Acura",
                    "MDX 3.5 4WD", "Driveshaft & Axle",
                    "Axle Nut 24mm x 1;5; rear ", 2.35);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(920495, 2006, "BMW",
                    "325i", "Climate Control",
                    "Adjustable Telescoping Mirror", 7.95);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(204075, 2004, "Acura",
                    "MDX 3.5 4WD", "Driveshaft & Axle",
                    "Wheel Bearing; Rear; 1 per wheel",
                    70.15);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(979304, 2000, "Toyota",
                    "RAV4 2WD/4-DOOR", "Cooling System",
                    "Thermostat Housing", 20.95);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(300456, 2004, "Acura",
                    "MDX 3.5 4WD", "Driveshaft & Axle",
                    "Wheel Bearing; Front; 1 per wheel", 66.65);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(404860, 2001, "Ford",
                    "Taurus LX V6 3.0", "Suspension",
                    "Shock Absorber GR2; Rear; Wagon only",
                    39.40);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(585688, 2007, "Buick",
                    "Lacrosse CXS V6 3.6", "Brake",
                    "Climate Control", 10.65);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(739759, 2001, "Ford",
                    "Taurus LX V6 3.0", "Suspension",
                    "Shock Absorber GasaJust; Rear; Wagon only", 30.95);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(927495, 2005, "Volvo",
                    "S40 2.5L T5 AWD", "Engine Mechanical",
                    "Timing Belt Idler Pulley Original Equipment INA",
                    65.55);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(979374, 2000, "Toyota",
                    "RAV4 2WD/4-DOOR", "Cooling System",
                    "Thermostat Gasket", 4.95);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(542347, 2007, "Buick",
                    "Lacrosse CXS V6 3.6", "Brake",
                    "Brake Pad Set ProACT Ceramic w/Shims; Front", 80.05);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(683064, 2000, "Toyota",
                    "RAV4 2WD/4-DOOR", "Cooling System",
                    "Radiator Hose; Upper", 103.75);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(248759, 1999, "Jeep",
                    "Wrangler Sahara", "Air Intake",
                    "Air Filter", 50.95);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(973974, 2007, "Toyota",
                    "Corolla", "Air Intake",
                    "Air Mass Meter; W/o Housing; Meter/sensor only",
                    134.95);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(285800, 2001, "Ford",
                    "Escape XLT 4WD", "Transmission", "AT Filter", 34.95);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(207495, 2007, "Toyota",
                    "Corolla", "Body Electrical",
                    "Headlight Bulb; 12V 65W; inner-high beam", 9.35);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(566676, 2000, "Toyota",
                    "RAV4 2WD/4-DOOR", "Cooling System",
                    "Auxiliary Fan Switch", 42.95);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(304950, 2007, "Toyota",
                    "Corolla", "Body Electrical",
                    "Headlight Bulb; 12V 51W; outer", 7.85);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(797394, 2000, "Toyota",
                    "RAV4 2WD/4-DOOR", "Cooling System",
                    "Water Flange Gasket", 0.85);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(910203, 2007, "Buick",
                    "Lacrosse CXS V6 3.6", "Suspension",
                    "Strut Mount Inc; Sleeve; Rear Right", 80.85);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(790794, 2000, "Toyota",
                    "RAV4 2WD/4-DOOR", "Cooling System",
                    "Radiator Hose; Lower", 9.45);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(970394, 2007, "Buick",
                    "Lacrosse CXS V6 3.6", "Suspension",
                    "Coil Spring Insulator; Front Lower", 14.55);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(290840, 2005, "Volvo",
                    "S40 2.5L T5 AWD", "Engine Mechanical",
                    "Rod Bearing Set 1 per Rod; Standard; Reqs. 5-per Engine",
                    26.95);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(209704, 2007, "Toyota",
                    "Corolla", "Body Electrical",
                    "Wiper Blade Excel+; Front Right", 7.25);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(200368, 2000, "Toyota",
                    "RAV4 2WD/4-DOOR", "Cooling System",
                    "Radiator Drain Plug incl; gasket", 3.15);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(200970, 2005, "Volvo",
                    "S40 2.5L T5 AWD", "Engine Mechanical",
                    "Reference Sensor; Flywheel Engine Speed", 62.05);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(542347, 2007, "Buick",
                    "Lacrosse CXS V6 3.6", "Air Intake",
                    "Air Filter", 50.25);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(927045, 2001, "Ford",
                    "Escape XLT 4WD", "Air Intake",
                    "Air Filter", 62.95);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(990659, 2000, "Toyota",
                    "RAV4 2WD/4-DOOR", "Cooling System",
                    "Radiator OE Plastic tank", 136.85);
                lstParts->Add(part);
    
                part = gcnew CPartDescription(440574, 2007, "Buick",
                    "Lacrosse CXS V6 3.6", "Suspension",
                    "Strut Mount Inc; Sleeve; Rear Left", 80.80);
    }
  15. Return to the form and double-click the Year combo box
  16. To display the list of car makes when the user selects a year, implement the event as follows:
    System::Void cbxYears_SelectedIndexChanged(System::Object^  sender, System::EventArgs^  e)
    {
        cbxMakes->Text = "";
        cbxMakes->Items->Clear();
        cbxModels->Text = "";
        cbxModels->Items->Clear();
        cbxCategories->Text = "";
        cbxCategories->Items->Clear();
    
        for each(CPartDescription ^ part in lstParts)
            if( part->CarYear == int::Parse(cbxYears->Text) )
                if( cbxMakes->FindString(part->Make) == -1 )
                    cbxMakes->Items->Add(part->Make);
    }
  17. Return to the form and double-click the Make combo box
  18. To display the list of car models when the user has selected a year and a make, implement the event as follows:
    System::Void cbxMakes_SelectedIndexChanged(System::Object^  sender, System::EventArgs^  e)
    {
        cbxModels->Text = "";
        cbxModels->Items->Clear();
        cbxCategories->Text = "";
        cbxCategories->Items->Clear();
    
        for each(CPartDescription ^ part in lstParts)
            if( (part->CarYear == int::Parse(cbxYears->Text)) &&
                (part->Make == cbxMakes->Text) )
                if( cbxModels->FindString(part->Model) == -1 )
                    cbxModels->Items->Add(part->Model);
    }
  19. Return to the form and double-click the Model combo box
  20. To display the list of categories after the user has selected the year, the make, and the model, implement the event as follows:
    System::Void cbxModels_SelectedIndexChanged(System::Object^  sender, System::EventArgs^  e)
    {
    	for each(CPartDescription ^ part in lstParts)
            if( (part->CarYear == int::Parse(cbxYears->Text)) &&
                (part->Make == cbxMakes->Text) &&
                (part->Model == cbxModels->Text) )
                if( cbxCategories->FindString(part->Category) == -1 )
                    cbxCategories->Items->Add(part->Category);
    }
  21. Return to the form and double-click the Category combo box
  22. To display the list of available parts, implement the event and define a new member function  as follows:
    System::Void cbxCategories_SelectedIndexChanged(System::Object^  sender, System::EventArgs^  e)
    {
        // Check each record in the list of parts
        for each(CPartDescription ^ part in lstParts)
        {
    	// If/When you find a record that matches 
    	// the values of the combo boxes . . .
            if( (part->CarYear == int::Parse(cbxYears->Text)) &&
                (part->Make == cbxMakes->Text) &&
                (part->Model == cbxModels->Text) &&
                (part->Category == cbxCategories->Text) )
            {
    	    // . . . get the values from that part and create a selected part
                CPartSelected ^ selected = gcnew CPartSelected(part->PartNumber,
    						           part->PartName,
    						           part->UnitPrice);
    	    // Store that part in the binding source
                bsPartsSelected->Add(selected);
            }
        }
    
        // Empty the data grid view
        for(int i = 0; i < dgvAvailableParts->Rows->Count - 2; i++ )
            dgvAvailableParts->Rows->RemoveAt(i);
    
        // Display the selected item(s) in the data grid view
        dgvAvailableParts->DataSource = bsPartsSelected;
    }
  23. Return to the form and double-click the Close button
  24. Implement the event as follows:
    System::Void btnClose_Click(System::Object^  sender, System::EventArgs^  e)
    {
        Close();
    }

Finding a String in the Combo Box

Instead of simply selecting an item from a combo box, the user may want to find out if a certain string exists in the  list. To support this operation, the ComboBox class is equipped with a member function named FindString that is overloaded with two versions. One of the syntaxes of this member function is:

public:
    int FindString(String^ s);

This member function takes as argument the string to find in the combo box. If the item is found in the list, the member function returns its position. If the list does not have that string, the member function return -1. The above syntax of the member function would look through the whole list. If you want the search to start at a specific index, you can use the following version of the FindString() member function:

public:
    int FindString(String^ s, int startIndex);

This version takes a string as the first argument. Instead of start looking for it from the beginning of the list, this member function starts at the index specified by the startIndex value.

The FindString() member function performs its operation without regards to case. This means that it would perform the same search for BlindMan, Blindman, blindMan, or BLINDMAN and would produce the same result for them. If you want the case of the characters to be taken into consideration, use the FindStringExact() member function that also is overloaded with two versions. The syntax of the first version is:

public:
    int FindStringExact(String^ s);

This member function proceeds like the FindString() member function by starting to look for the string from the beginning of the list. If you want to specify from where to start looking for the string, you should use the following version:

public:
    int FindStringExact(String^ s, int startIndex);
 
 
 

The Styles of a Combo Box

 

The Flat Styles

Like most graphical controls, a combo box appears as a 3-D object with raised borders. As an alternative, you can display it as a flat object. To assist you with this choice, the ComboBox class provides the FlatStyle property. The FlatStyle property is based on the FlatStyle enumeration. Its members are:

  • Standard: This is the default value of the property. It makes the control appear with raised borders:
     
    void InitializeComponent()
    {
        lblTitle = gcnew Label;
        lblTitle->Text = "Academic Disciplines";
        lblTitle->Location =  Point(12, 12);
        lblTitle->AutoSize = true;
        Controls->Add(lblTitle);
    
        cbxAcademicDisciplines = gcnew ComboBox;
        cbxAcademicDisciplines->Location =  Point(12, 32);
        cbxAcademicDisciplines->Width = 200;
        cbxAcademicDisciplines->FlatStyle = FlatStyle::Standard;
    
        cbxAcademicDisciplines->Items->Add("Natural sciences");
        cbxAcademicDisciplines->Items->Add("Mathematics and Computer sciences");
        cbxAcademicDisciplines->Items->Add("Social sciences");
        cbxAcademicDisciplines->Items->Add("Humanities");
        cbxAcademicDisciplines->Items->Add("Professions and Applied sciences");
    
        array<String ^> ^ disciplines = gcnew array<String ^>(3);
    
        disciplines[0] = "Business Administration";
        disciplines[1] = "Criminal Justice";
        disciplines[2] = "Art History";
        cbxAcademicDisciplines->Items->AddRange(disciplines);
    
        Controls->Add(cbxAcademicDisciplines);
    }
  • Popup: The control will appear flat with a surrounding gray line:
     
    cbxAcademicDisciplines->FlatStyle = FlatStyle::Popup;
    Popup Combo Box
  • Flat: The control appears flat with a white surroundiong border:
     
    cbxAcademicDisciplines->FlatStyle = FlatStyle::Flat;
  • System: The user's operating system (and theme, if any) will determine how the control must appear

The Drop Down Style

In our introduction to the combo box, we saw that it appeared like a text box with a down-pointing button on its right side. In reality, that was the description of just one type of combo box. There are three styles of combo boxes, although all allow the user to make only one selection. These styles are controlled by the DropDownStyle property, which is based on the ComboBoxStyle enumeration.

One of the types of combo boxes is referred to as Drop Down and is created by setting the DropDownStyle property to DropDown. Here is an example:

void InitializeComponent()
{
    lblTitle = gcnew Label;
    lblTitle->Text = "Academic Disciplines";
    lblTitle->Location =  Point(12, 12);
    lblTitle->AutoSize = true;
    Controls->Add(lblTitle);

    cbxAcademicDisciplines = gcnew ComboBox;
    cbxAcademicDisciplines->Location =  Point(12, 32);
    cbxAcademicDisciplines->Width = 200;

    cbxAcademicDisciplines->DropDownStyle = ComboBoxStyle::DropDown;

    cbxAcademicDisciplines->Items->Add("Natural sciences");
    cbxAcademicDisciplines->Items->Add("Mathematics and Computer sciences");
    cbxAcademicDisciplines->Items->Add("Social sciences");
    cbxAcademicDisciplines->Items->Add("Humanities");
    cbxAcademicDisciplines->Items->Add("Professions and Applied sciences");

    array<String ^> ^ disciplines = gcnew array<String ^>(3);

    disciplines[0] = "Business Administration";
    disciplines[1] = "Criminal Justice";
    disciplines[2] = "Art History";
    cbxAcademicDisciplines->Items->AddRange(disciplines);

    Controls->Add(cbxAcademicDisciplines);
}

This type is made of a text box on the left side and a down-pointing arrowed button on the right side. Depending on how the control was created, when it comes up, it may not display anything:

A Drop Down Combo Box

Normally, if you want a DropDown style of combo box to display a string when the control comes up, you can either enter a value in the Text property or assign a string to the ComboBox.Text property. Here is an example:

void InitializeComponent()
{
    lblTitle = gcnew Label;
    lblTitle->Text = "Academic Disciplines";
    lblTitle->Location =  Point(12, 12);
    lblTitle->AutoSize = true;
    Controls->Add(lblTitle);

    cbxAcademicDisciplines = gcnew ComboBox;
    cbxAcademicDisciplines->Location =  Point(12, 32);
    cbxAcademicDisciplines->Width = 200;

    cbxAcademicDisciplines->Items->Add("Natural sciences");
    cbxAcademicDisciplines->Items->Add("Mathematics and Computer sciences");
    cbxAcademicDisciplines->Items->Add("Social sciences");
    cbxAcademicDisciplines->Items->Add("Humanities");
    cbxAcademicDisciplines->Items->Add("Professions and Applied sciences");

    array<String ^> ^ disciplines = gcnew array<String ^>(3);

    disciplines[0] = "Business Administration";
    disciplines[1] = "Criminal Justice";
    disciplines[2] = "Art History";
    cbxAcademicDisciplines->Items->AddRange(disciplines);
        
    cbxAcademicDisciplines->Text = "Social sciences";

    Controls->Add(cbxAcademicDisciplines);
}

This would produce:

The Text of a Combo Box

The string you give to the Text property does not have to be one of the items of the list. 

To use the combo box, the user can click its down pointing arrow. At any time, to find out whether the list is displaying, you can check the value of the DroppedDown Boolean property. In the same way, to drop the list, you can programmatically set the combo box' DroppedDown property to true.

Once the list is displaying, if the user clicks that arrow, a list would appear (or expand). If the string assigned to the Text property is one of the items in the list, it would display in the text box side of the control and it would be selected in the list. Here is an example:

void InitializeComponent()
{
        lblTitle = gcnew Label;
        lblTitle->Text = "Academic Disciplines";
        lblTitle->Location =  Point(12, 12);
        lblTitle->AutoSize = true;
        Controls->Add(lblTitle);

        cbxAcademicDisciplines = gcnew ComboBox;
        cbxAcademicDisciplines->Location =  Point(12, 32);
        cbxAcademicDisciplines->Items->Add("Natural Sciences");
        cbxAcademicDisciplines->Items->Add("Mathematics and Computer Sciences");
        cbxAcademicDisciplines->Items->Add("Social Sciences");
        cbxAcademicDisciplines->Items->Add("Humanities");
        cbxAcademicDisciplines->Items->Add("Professions and Applied Sciences");

        cbxAcademicDisciplines->DropDownStyle = ComboBoxStyle::DropDown;
        cbxAcademicDisciplines->Text = "Social Sciences";

        Controls->Add(cbxAcademicDisciplines);
}

This would produce:

Using a DropDown combo box

If the string assigned to the Text property is not one of the items in the list, it would still appear selected in the text box side of the control:

Here is an example:

void InitializeComponent()
{
    lblTitle = gcnew Label;
    lblTitle->Text = "Academic Disciplines";
    lblTitle->Location =  Point(12, 12);
    lblTitle->AutoSize = true;
    Controls->Add(lblTitle);

    cbxAcademicDisciplines = gcnew ComboBox;
    cbxAcademicDisciplines->Location =  Point(12, 32);
    cbxAcademicDisciplines->Width = 200;

    cbxAcademicDisciplines->DropDownStyle = ComboBoxStyle::DropDown;

    cbxAcademicDisciplines->Items->Add("Natural sciences");
    cbxAcademicDisciplines->Items->Add("Mathematics and Computer sciences");
    cbxAcademicDisciplines->Items->Add("Social sciences");
    cbxAcademicDisciplines->Items->Add("Humanities");
    cbxAcademicDisciplines->Items->Add("Professions and Applied sciences");
	
    cbxAcademicDisciplines->Text = "Arts & Sciences";

    Controls->Add(cbxAcademicDisciplines);
}

This would produce:

When the list displays, either because the user clicked the arrow button, pressed Alt + the down arrow key or because you decided to display it, the control fires a DropDown event, which is of type EventArgs.

If the user sees an item that he or she wants or was asked to select, he or she can click it. After an item has been clicked, two things happen: 1. the list retracts (or collapses) like a plastic; 2. the item that was clicked fills the text part and becomes the new selection:

Selecting an existing item in a DropDown combo box After selecting an item from a DropDown combo box

On the other hand, after displaying the list, if the user doesn't want to select anything from the list, he or she can click the arrow again or click anywhere away from the list. The list would collapse and the text part would get back to the previous text.

One of the major characteristics of a DropDown style of combo box, as compared to the type we will see next, is that, if the user knows for sure that the item he or she is looking for is in the list, he can first delete the string in the text box part of the control, then start typing. For example, if the list contains a string such as Social Sciences, the user can delete the text part, and start typing so. If there is only one item that starts with s, the user can then click the arrow twice and the item would be selected. Imagine the list contains such items as Jules and Julienne, if the user types the first common letters of these item and double-click the arrow, the first item that has these letters would be selected. This means that, if the user wants to other item to be selected, he or she should type the letters beyond the common ones. In the case of Jules and Julienne, if the user wants Julienne to be selected from an incomplete string, he or she can type juli and click the arrowed button twice.

The Drop Down List

Another style of a combo box is gotten by setting the DropDownStyle to DropDownList. This type also is made of a text box on the left and a down-pointing arrowed button on the right side. It also may appear empty when it comes up, depending on how it was created. The biggest difference between a DropDown combo box and a DropDownList combo box is that, with the drop down list, the user can only select from the list: he or she cannot type anything in the text box part of the control.

Once again, to use the control, the user can click its arrow, which causes the list to display. The user can also display the list using the keyboard by pressing Alt + down arrow key after giving focus to the control.

ApplicationPractical Learning: Applying a Style to a Combo Box

  1. The CPAP1 project should still be opened.
    On the form, click the Make combo box
  2. In the Properties window, click DropDownStyle, then click the arrow of its combo box and select DropDownList
  3. On the form, click the Model combo box
  4. Press and hold Shift
  5. Click the Category combo box
  6. Release Shift
  7. In the Properties window, click DropDownStyle, then click the arrow of its combo box and select DropDownList
  8. To execute the application to test it, on the Standard toolbar, click Start Without Debugging
     
    College Park Auto Parts
     
    College Park Auto Parts
     
    College Park Auto Parts
  9. After using it, close the form and return to your programming environment

The Simple Combo Box

The last type of combo box is called a simple combo box and is gotten by setting the DropDownStyle to Simple. After setting this value, you must heighten the control to get the desired size. This type of combo box is also made of two parts but they are distinct. The top section of the combo box displays a text box. Immediately under the text box, there is a list box. The following is the Character dialog box of OpenOffice.org. Its Font property page is equipped with the Font, the Typeface, and the Size combo boxes that are of a Simple style:

The Simple Combo Box

Notice that the control doesn't display a down-arrow pointing button on the right side of the selected item since the list is available already. To use this combo box, the user can examine the list part. If he or she sees the desired item, he can click it. When an item is clicked, it becomes the string of the top text part. If the user clicks a different item, it would become the new selection, replacing the one that was in the text part. Although this appears as a list box, the user cannot select more than one item.

The most regularly used combo boxes are made of text items. You can also create a combo box that displays colors or pictures. To create such a combo box, you start by changing the value of the DrawMode property that is set to Normal by default. If you want to display items that are not just regular text, you can set this property to either OwnerDrawFixed, which would make all items have the same height, or OwnerDrawVariable, which allows different items to have different sizes.

If the combo box has a DropDownStyle other than Simple, there is typically a fixed number of items that display when the user clicks the control's arrow. You can control the number of items that displays using the MaxDropDownItems property. By default, this is set to 8. If the list contains a number of items less than the MaxDropDownItems integer value, all of the items would display fine. If the list contains more than the MaxDropDownItems number of items, when the user clicks the arrow, a vertical scroll box would appear. The control would display MaxDropDownItems number of items; to reveal more, the user would have to scroll in the list.

Automatic List Creation

 

Using an External List

 

In previous sections, we saw how to create a list of items. The .NET Framework provides an alternative. Instead of creating a list from scratch, you can use one that exists already. For example, you can use a list of recently accessed web sites or custom list of your own. To assist you with this, the ComboBox class provides three techniques.

To specify an external list of items to use for the combo box, you have two options. You can use the AutoCompleteSource property that is based on the AutoCompleteSource enumeration. The members of this enumeration are: None, RecentlyUsedList, FileSystem, FileSystemDirectories, HistoryList, ListItems, AllSystemSources, AllUrl, and CustomSource. Imagine that you want to use the list of web pages you had visited lately. To use that list, you can specify the AutoCompleteSource as HistoryList.

After specifying the source of the list, use the AutoCompleteMode property to specify how the combo box (or rather the text box side of the control) will assist the user. This property is based on the AutoCompleteMode enumeration that has four members. None is the default value. Imagine you had set the value of the AutoCompleteSource property as HistoryList. If you specify AutoCompleteMode as:

  • Suggest: In the text box part of the combo box, the user can click and start typing. A list of closely-matched items would display:
     


    In this case, as soon as the user types h, a list of URLs that start with h (for http) would come up. Once the user sees the desired item, he or she can then click that item to select it. Since there are many items, to continuously narrow the list, the user can keep typing until the desired item comes up
  • Append: In the text box part, the user can start typing. The control would then start looking for the closest matches and try to complete the user's entry with those available. Here is an example:
     

    First the user types h and http:// comes up as the first closest match. Then, the user specifies that the address starts with m and the compiler suggests, in alphabetical order, the closest URL with that. Then, the user types ms and finds out that msdn2 is available

  • SuggestAppend: This is a combination of the previous two options. When the control comes up, the user can start typing. The control would then display the list of items that start with what the user typed and it would display the starting closest match
     

    The user can continue typing. If the desired item appears in the list, the user can select it. Otherwise, as the user is typing, the closest match displays in the text box part of the control

    Combo Box Combo Box

Using a Custom List

 

Instead of using an external list, you can create your own. To do this, use the AutoCompleteCustomSource property. At design time, to create a list of strings, access the Properties window for the text box. In the Properties window, click the ellipsis button of the AutoCompleteCustomSource field to open the String Collection Editor. Enter the strings separated by a hard Return, and click OK. You can also programmatically create the list. To assist you, the .NET Framework provides a class named AutoCompleteStringCollection. The AutoCompleteStringCollection class implements the IList, the ICollection, and the IEnumerable interfaces.

After creating the custom list, to let the combo box use it, set the AutoCompleteMode property to CustomSource.

ApplicationPractical Learning: Auto Completing a Combo Box

  1. To re-open a previously used project, on the main menu, click File -> Recent Projects and Solutions -> ClarksvilleIceCream3
  2. On the form, click the Flavor combo box
  3. In the Properties window, click AutoCompleteSource, then click the arrow of its combo box, and select ListItems
  4. Click the AutoCompleteMode, then click the arrow of its combo box, and select SuggestAppend
  5. On the form, double-click Calculate
  6. Implement the event as follows:
    System::Void button1_Click(System::Object^  sender, System::EventArgs^  e)
    {
        double priceContainer = 0.00,
        priceIngredient = 0.00,
        priceScoops = 0.00,
        orderTotal = 0.00;
        int numberOfScoops = 1;
    
        // Find out what container the customer requested
        // The price of a container depends on which one the customer selected
        if( cbxContainers->Text == "Cone" )
            priceContainer = 0.55;
        else if( cbxContainers->Text == "Cup" )
            priceContainer = 0.75;
        else
            priceContainer = 1.15;
    
        // If the customer selected an ingredient, which is not "None", add $.95
        if( cbxIngredients->Text != "None" )
            priceIngredient = 0.95;
    
        try
        {
            // Get the number of scoops
            numberOfScoops = int::Parse(txtScoops->Text);
    
            if( numberOfScoops == 2)
                priceScoops = 2.55;
            else if( numberOfScoops == 3)
                priceScoops = 3.25;
            else
                priceScoops = 1.85;
        }
        catch(FormatException ^)
        {
            MessageBox::Show("The value you entered for the scoops is not valid"
                            "\nOnly natural numbers such as 1, 2, or 3 are allowed"
                            "\nPlease try again", "Clarksville Ice Cream",
                            MessageBoxButtons::OK, MessageBoxIcon::Information);
        }
    
        // Make sure the user selected a flavor, 
        // otherwise, there is no reason to process an order
        if( cbxFlavors->Text != "")
            orderTotal = priceScoops + priceContainer + priceIngredient;
    
        txtOrderTotal->Text = orderTotal.ToString("F");
    }
  7. To execute, press F5
  8. Close the form and return to your programming environment
 
 
   
 

Home Copyright © 2011 FunctionX, Inc. Home