Home

List Box Controls

 

List Boxes

 

Introduction

A list box presents a list of items to choose from. Each item displays on a line. The user makes a selection by clicking in the list. Once clicked, the item or line on which the mouse landed becomes highlighted, indicating that it is the current choice. After an item has been selected, to make a different selection, the user would click another. She can also press the up and down arrow keys to navigate through the list and make a selection.

A list box can also be configured to allow multiple selections.

The Date and Time Dialog Box

One of the main reasons for using a list box is to display a list of items to the user. Sometimes the list would be very large. If the list is longer than the available space on the control, the control would be equipped with a scroll bar that allows the user to navigate up and down to access all items of the list. You will have the option of deciding how many items to display on the list.

List Box Creation

A list box is immediately derived from the TCustomListBox class and that is where its properties are set. There are three main ways you add a list box to your form.

 

To create a list box, you can click the ListBox control ListBox from the Standard section of the Tool Palette and click on the form. Once the list box is positioned on a container, you can move it by clicking and dragging the control. You can also resize it using any of the techniques we learned to add, position, move, and resize controls on a component. If the list will cover many items, design it so its height can display 8 items at a time. Otherwise, for a list of 8 or less items, use only the necessary height that would accommodate all of the items.

List Box Properties

The most fundamental and the most obvious aspect of a list box is the list of items it displays. The list of items of this control is a TStrings object. If you know the list of items for the control, there are two easy ways you can create it. At design time, on the Object Inspector, you can click the Items property to reveal its ellipsis button on the right field . To create the list, click this button to call the String List Editor, type each item desired, on its own line by pressing Enter:

The String List Editor Dialog Box

To programmatically add the items to a list box, use the TStrings::Add() method. If the list were empty, the new items would be added to the list. If the list already contained one or more items, the new items would be added, by default, to the end of the existing one(s). Here is an example of creating a list of items or adding new ones to a list:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
	ListBox1->Items->Add("Chad");
	ListBox1->Items->Add("Equatorial Guinea");
	ListBox1->Items->Add("Egypt");
	ListBox1->Items->Add("Madagascar");
}
//---------------------------------------------------------------------------

Alternatively, to add an item or items to a list box, you can call the Win32 API’s SendMessage() function with the LP_ADDSTRING as the message. The wParam argument is not used and can be passed as 0. The string to add must be null-terminated and must be cast to LPARAM. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
	SendMessage(ListBox1->Handle, LB_ADDSTRING, 0, (LPARAM)("Edem Kodjo"));
}
//---------------------------------------------------------------------------

As mentioned already, the user mostly interacts with a list box by selecting an item. At any time you can find out whether a particular item has been selected. This is done using the TCustomListBox::Selected Boolean property.

When the Items of a list box appear in alphabetical order, the list is said to be sorted. By default, the items of a list box are not sorted. To arrange the list to ascending order, set the Sorted property’s value to true. As a Boolean data type, you can set the sorting feature programmatically as follows:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	ListBox1->Sorted = True;
}
//---------------------------------------------------------------------------

If you create an unsorted list, then at one time get it sorted (for example, you can give the user the ability to sort the list, by clicking a button), the list would be sorted. If an item is added to the sorted list, the compiler would automatically insert to the right position following the order. If at another time you allow the user to “unsort” the list, the list would keep its current order. If another item is added when the list is not sorted, the item would be positioned at the end of the list. If you want the list to have its original state, you would have to reset it through code.If you change the Color property of the ListBox control, its whole background would appear with that color. If you want each item to have its own color, you would have to change the style of the list and properly configure it.

When you create a list of items, they appear in one range of columns. If the number of items exceeds the height, a scrollbar would appear on the control. One alternative you can use is to span the list on more than one column. This is set using the Columns property. By default, the Columns value is set to 0, which means the items appear in one column.

If you position the control on a form whose DockSite property is set to true with the control having a DragKind property dkDock and the DragMode property set to dmAutomatic, the user will be able to move the control and position it anywhere inside the form.

By default, the user can select only one item in the list. This is controlled by both the ExtendedSelect and the MultiSelect properties. If you want the user to be able to select more than one item, you should set the MultiSelect property to true since the ExtendedSelect property would already be set to true. After the user has selected more than one item, you can use the TCustomList::SelCount to find out the number of items that the user would have selected.

The list boxes are designed in three types of style. The default is the lbStandard in which case each item in the list is an AnsiString object. On the other hand, if you want each item of the list to display a graphic or a color, you must set the style to an owner draw. The lbOwnerDrawFixed allows you to set a desired height for each item of the list. This height is controlled through the ItemHeight property. You can set a different height for each item if you set the list style to lbOwnerDrawVariable.

The ItemIndex is a property that identifies which item is selected in a list box. This is a property of highly particular interest. If you try performing an operation that requires that an item be selected and no item is selected, the program would throw an error. The items in a list box are counted from 0, then 1, etc. The first item, at position 0, can be identified as ListBox1->ItemIndex = 0. If no item is selected in the list, the TCustomListBox::ItemIndex has a value of –1.During introduction, we saw that if a List Box includes more items than the vertical size, the Height, allows displaying, the control would be equipped with a vertical scroll that would allow the user to move up and down and access the whole list. If at least one of the items is wider than the control can display, this might not be obvious to the user. You would have to provide the control with a horizontal scroll bar. The Win32 provides a SendMessage() function that can take care of this. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
	SendMessage (ListBox1->Handle, LB_SETHORIZONTALEXTENT, 200, 0);
}
//---------------------------------------------------------------------------

The items of a list box are AnsiString objects created from the TStrings class. This allows you to use the properties of the TStrings class. We will study the TStrings class in another lesson.

List Box Methods

The only methods a list box has on its own are its constructor and its destructor. The TListBox is typically used to dynamically create a list box. To create a list box inside of an event or a function, use the new operator. To do this, declare a pointer to a TListBox class. When declaring this object, the constructor of the TListBox needs to know the component that owns the control; this is usually the host or container of the list box. If the List Box will be placed on a form called Form1, you can create the List Box as follows:

//---------------------------------------------------------------------------
void __fastcall TForm1::CreateTheList()
{
	TListBox* Liste = new TListBox(this);
	Liste->Parent = Form1;
}
//---------------------------------------------------------------------------

If the list box will be positioned on another type of container, such as a panel called Panel1, you can create it as follows:

//---------------------------------------------------------------------------
void __fastcall TForm1::CreateTheList()
{
	TListBox* Liste = new TListBox(this);
	Liste->Parent = Panel1;
}
//---------------------------------------------------------------------------

If you create the list box in a function, a method, or an event, the list will exist only inside of that function: you cannot manipulate it from another function, method, or event. If you want the control to be accessed by many functions declare a TListBox object in the header file of the form where the control will be hosted.. Here is an example:

//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
private: // User declarations
	TListBox *Listing;
public: // User declarations
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

After declaring the control, you should initialize it in the form’s constructor. This allows you to specify the container that will host the control:

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	Listing = new TListBox(Form1);
	Listing->Parent = Form1;
	Listing->Left = 120;
	Listing->Top = 80;
}
//---------------------------------------------------------------------------

When an application terminates, Borland C++ Builder takes care of destroying all of the objects that are part of the application. If the objects were created at design time, they are owned by the form. Since the form is owned by the application, the application would destroy the form including its hosted controls. If a control was placed on another container such as a panel, the panel is owned by the form and the form by the application. The destruction would still be smooth when the application executes. If you dynamically create a control, you must specify the owner of the control; otherwise the program would not compile. Since you will have specified the owner or container of the control, when the application exits, the compiler would destroy the form and its control, which would include the control you dynamically created. Therefore, you do not have to worry about the state of the dynamic controls when your application exits. This does not mean that your application would never produce a memory leak, but it would be highly unlikely.

If you want to explicitly destroy your dynamically created object, the best place to destroy a global object is to use the delete operator on the OnDestroy event of the form:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
	delete Listing;
	Listing = NULL;
}
//---------------------------------------------------------------------------

If the list box was dynamically created inside of a function, you cannot access it outside of that function. If it were declared in the header file, you can use any appropriate method, event, or function to fill the list or to manipulate the control. For example, you can fill out the Listing control we declared earlier as follows:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	Listing->Items->Add("C++ Builder");
	Listing->Items->Add("Delphi");
	Listing->Items->Add("JBuilder");
	Listing->Items->Add("Kylix");
}
//---------------------------------------------------------------------------

Since the items of a list box are derived from the TStrings class, you can use this class’ methods to perform the desired operations on the control. The strings in a list box are counted starting at 0, then 1, and so on.To add an item at the end of the list, you can write code such as:

//---------------------------------------------------------------------------
void __fastcall TForm1::btnAddLesothoClick(TObject *Sender)
{
	lstCountries->Items->Add("Lesotho");
}
//---------------------------------------------------------------------------

To insert an item in the 2nd position you can write code such as:

//---------------------------------------------------------------------------
void __fastcall TForm1::btnAddSecondClick(TObject *Sender)
{
	lstCountries->Items->Insert(1, "Mauritania");
}
//---------------------------------------------------------------------------

To delete the 4th item of the list, you could write:

//---------------------------------------------------------------------------
void __fastcall TForm1::btnDelete4Click(TObject *Sender)
{
	lstCountries->Items->Delete(3);
}
//---------------------------------------------------------------------------

If the list contains less than 4 items, the TStrings::Delete() method would ignore the operation. If you have an Edit control called edtCountry, you can let the user add its content to the list box when he double-clicks the edit box. The code could look as follows:

//---------------------------------------------------------------------------
void __fastcall TForm1::Edit1DblClick(TObject *Sender)
{
	lstCountries->Items->Add(edtCountry->Text);
}
//---------------------------------------------------------------------------

If the user is filling out a list box while typing additional items in an Edit control, the best and fastest way to add a new item is when the user presses Enter after typing the item. To implement this behavior, you should find out what key the user pressed. If the user presses Enter when the edit box has focus, you should make sure the edit box contains a string. The code could appear like this:

//---------------------------------------------------------------------------
void __fastcall TForm1::Edit1KeyPress(TObject *Sender, char &Key)
{
	if( Key == 13 ) // If the user presses the Enter key
	{
		if(Edit1->Text != "") // If Edit1 contains something
		{
			lstCountries->Items->Add(Edit1->Text);
			// Add the content of Edit1 to ListBox1
			Edit1->Text = ""; // Reset Edit1 and make it empty
		}
		else // Since Edit1 is empty, display a message
			Panel1->Caption = "There is nothing to add";
	}
}
//---------------------------------------------------------------------------

The TCustomListBox::Clear() method is used to clear the control of its whole content:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
	lstCountries->Clear();
}
//---------------------------------------------------------------------------

Operations on List Boxes

The most regular operation users perform on a list box is to select items. This selection is performed by the user clicking one of the items. Using code, you can also select an item in the list. To select the 6th item of the list, you could write the code as:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	lstCountries->ItemIndex = 6;
}
//---------------------------------------------------------------------------

When performing your operations, sometimes you will want to find out if a particular item is selected. You can do this using the ordinal position of the item. For example, to find out if the 3rd item is selected, you can write:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button7Click(TObject *Sender)
{
	if( lstCountries->ItemIndex == 2)
		Panel1->Caption = "The third item is selected";
}
//---------------------------------------------------------------------------

If an item is selected, you can allow the user to perform an operation on it. If a string (that is, any string) is not selected, most operations would fail and the program would crash. Therefore, usually you should make sure an item is selected. An item is selected when the value of the TCustomListBox::ItemIndex integer value is not negative. Operations include displaying the selected item of the list box to an edit box:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button6Click(TObject *Sender)
{
	// First find out whether an item is selected
	if(lstCountries->ItemIndex != -1) // Put the selected item in the edit
		Edit1->Text = lstCountries->Items->Strings[lstCountries->ItemIndex];
}
//---------------------------------------------------------------------------

inserting a new string above the selected item:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button6Click(TObject *Sender)
{
	lstCountries->Items->Insert(lstCountries->ItemIndex, Edit1->Text);
}
//---------------------------------------------------------------------------

or under the selected string:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button6Click(TObject *Sender)
{
	lstCountries->Items->Insert(lstCountries->ItemIndex + 1, Edit1->Text);
}
//---------------------------------------------------------------------------

Many times during your design, you will allow users to add or delete items to or from a list box. One way you will do this is to create a list of items originating from another list; this allows you to control the items the user can select from a list before continuing with the issue at hand. Borland C++ Builder ships with a dialog box completely configured to handle this transaction.

To allow two list boxes to exchange data, you provide the appropriate buttons. If only one list will be used as the source, provide one button that could allow the user to select an item. It is also a good idea to allow the user to select and add all items at once. Also important is the ability for the user to remove mistakenly selected items. Over all, these kinds of list boxes handle their transactions through the use of four buttons: two are used to exchange one item at a time from one list to another, two to exchange all items from one list to another.

Practical Learning Practical Learning: Configuring List Boxes

  1. To start a new project, on the Standard toolbar, click the New button 
  2. Make sure the Application icon is selected and click OK
  3. To add Borland C++ Builder’s built-in list box dialog, on the Standard toolbar, click the New button . In the Object Repository, click the Forms property page
  4. Click the Dual List Box icon:
  5. Click OK
  6. To remove the starting form, press F12 to display the Code Editor
  7. Click the Unit1.cpp to select it
  8. Right-click the Unit1.cpp tab and click Close Page
  9. When asked whether you want to save Unit1, click No
  10. To test the application, press F9
  11. Use the existing transfer buttons to exchange items between both list boxes
  12. Close the form using its Windows Close button
  13. On the form, click the Source List label
  14. On the Object Inspector, click Caption and type Cities to locate on a map:
  15. Click Destination List and type Cities Selected:
  16. To remove the items in the list, click the left list to select it
  17. On the Object Inspector, click the ellipsis button of the Items field
    q Delete all items in the String List Editor dialog box and click OK
  18. To create our own list, double-click an unoccupied area of the form and implement the OnCreate event as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TDualListDlg::FormCreate(TObject *Sender)
    {
    	SrcList->Items->Add("Shangai");
    	SrcList->Items->Add("Melbourne");
    	SrcList->Items->Add("Kenitra");
    	SrcList->Items->Add("London");
    	SrcList->Items->Add("Valencia");
    	SrcList->Items->Add("Rio de Oro");
    	SrcList->Items->Add("Santiago");
    	SrcList->Items->Add("Dublin");
    	SrcList->Items->Add("Bamako");
    	SrcList->Items->Add("New Delhi");
    	SrcList->Items->Add("Tokyo");
    	SrcList->Items->Add("Alexandria");
    	SrcList->Items->Add("Boston");
    	SrcList->Items->Add("Quebec");
    	SrcList->Items->Add("Dar-Es-Salam");
    	SrcList->Items->Add("Munich");
    }
    //---------------------------------------------------------------------------
  19. Display the form
  20. Click the Cancel button and press Delete
  21. Also delete the Help button
  22. Double-click the OK button and implement its OnClick event as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TDualListDlg::OKBtnClick(TObject *Sender)
    {
    	Close();
    }
    //---------------------------------------------------------------------------
  23. To test the dialog box, press F9
  24. After using the list boxes, click OK to close the form
  25. Press F12 to display the form
  26. Click the left list to select it
  27. To make sure that double-clicking an item in the left list has the same effect as clicking the Include button, click the Events tab
  28. Double-click the event of the OnDblClick field and implement it as follows:
     
    void __fastcall TDualListDlg::SrcListDblClick(TObject *Sender)
    {
    	IncludeBtnClick(Sender);
    }
    //---------------------------------------------------------------------------
  29. Display the form and click the right list
  30. On the Object Inspector, double-click the event of the OnDblClick field and implement it as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TDualListDlg::DstListDblClick(TObject *Sender)
    {
    	ExcludeBtnClick(Sender);
    }
    //---------------------------------------------------------------------------
  31. To test the application, press F9
  32. After using the form, close it

 

 

Previous Copyright © 2005-2007 Yevol Next