Home

Windows Controls: The List Box

   

Introduction to List Boxes

 

Description

A list box presents a list of items to choose from. Each item displays on a line. Here is an example of a list box:

The Date and Time Dialog Box

The user makes a selection by clicking an item 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. The user 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.

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.

Practical LearningPractical Learning: Introducing List Boxes

  1. Start Embarcadero RAD Studio
  2. To create a new application, on the main menu, click File -> New -> VCL Forms Application - C++Builder
  3. In the Object Inspector, change the following properties:
    Caption: Solo Musical Instrument Store
    Name:    frmMusicalStore
    Position: poScreenCenter
  4. To save the project, on the main menu, click File -> Save All
  5. Click New Folder
  6. Type MusicalInstrumentStore1 as the name of the folder and press Enter twice to display the contents of that folder
  7. Change the unit file to MusicalStore and click Save
  8. Change the project name to MusicalInstrumentStore and click Save
  9. To create an XML file, on the main menu, click File -> New -> Other...
  10. In the left list, click Web Documents
  11. In the right list, click XML File
     
    New Items
  12. Click OK
  13. Complete the file with a few items as follows:
    <?xml version="1.0" encoding="UTF-8"?>
    <StoreItems>
      <StoreItem>
    	<ItemNumber>581705</ItemNumber>
    	<Category>Guitars</Category>
    	<Type>Electric</Type>
    	<ItemName>Gibson Les Paul Vintage Mahogany Electric Guitar</ItemName>
    	<UnitPrice>745.95</UnitPrice>
      </StoreItem>
      <StoreItem>
    	<ItemNumber>724475</ItemNumber>
    	<Category>Bass</Category>
    	<Type>Electric 4-String</Type>
    	<ItemName>Epiphone Thunderbird IV Bass</ItemName>
    	<UnitPrice>325.85</UnitPrice>
      </StoreItem>
      <StoreItem>
    	<ItemNumber>902735</ItemNumber>
    	<Category>Keyboards</Category>
    	<Type>Synthesizers</Type>
    	<ItemName>Alesis QS8.2 88 Key Synthesizer</ItemName>
    	<UnitPrice>825.50</UnitPrice>
      </StoreItem>
      <StoreItem>
    	<ItemNumber>793500</ItemNumber>
    	<Category>Guitars</Category>
    	<Type>Acoustic</Type>
    	<ItemName>Gretsch Guitars G100 Synchromatic Archtop Acoustic Guitar</ItemName>
    	<UnitPrice>595.95</UnitPrice>
      </StoreItem>
      <StoreItem>
    	<ItemNumber>297300</ItemNumber>
    	<Category>Drums</Category>
    	<Type>Drum Set</Type>
    	<ItemName>Pulse Pro 5-Piece Drum Set with Cymbals</ItemName>
    	<UnitPrice>395.95</UnitPrice>
      </StoreItem>
      <StoreItem>
    	<ItemNumber>931805</ItemNumber>
    	<Category>Keyboards</Category>
    	<Type>Pianos</Type>
    	<ItemName>Roland RD-700SX Digital Piano</ItemName>
    	<UnitPrice>2195.00</UnitPrice>
      </StoreItem>
      <StoreItem>
    	<ItemNumber>37940</ItemNumber>
    	<Category>Accessories</Category>
    	<Type>Cables</Type>
    	<ItemName>Mogami Gold AES/EBU Interconnect Cable with Neutrik XLR</ItemName>
    	<UnitPrice>45.85</UnitPrice>
      </StoreItem>
      <StoreItem>
    	<ItemNumber>207485</ItemNumber>
    	<Category>Guitars</Category>
    	<Type>Acoustic-Electric</Type>
    	<ItemName>Ibanez V Series V70CE Dreadnought Cutaway Acoustic-Electric Guitar</ItemName>
    	<UnitPrice>225.50</UnitPrice>
      </StoreItem>
      <StoreItem>
    	<ItemNumber>927358</ItemNumber>
    	<Category>Guitars</Category>
    	<Type>Electric</Type>
    	<ItemName>Schecter C-1 Hellraiser Electric Guitar</ItemName>
    	<UnitPrice>650.00</UnitPrice>
      </StoreItem>
      <StoreItem>
    	<ItemNumber>508384</ItemNumber>
    	<Category>Keyboards</Category>
    	<Type>Synthesizers</Type>
    	<ItemName>Roland V Synth GT Elastic Audio Synthesizer Keyboard</ItemName>
    	<UnitPrice>2895.50</UnitPrice>
      </StoreItem>
    </StoreItems>
  14. To save the file, on the Standard toolbar, click the Save All button Save All
  15. Change the file name to StoreItems and click Save
  16. Display the form
  17. From the Internet section of the Tool Palette, click TXmlDocument TXmlDocument and click the form
  18. In the Object Inspector, change the control's name to xdcStoreItems
  19. Click FileName then click its ellipsis button
  20. Locate the StoreItems.xml file, click it, and click Open
  21. Click the Active check box to make it True
  22. Save all

List Box Creation

To support list boxes, the VCL provides a class named TListBox. The TListBox class is immediately derived from the TCustomListBox class that actually holds its characteristics as a list-based control. The TListBox and the TCustomListBox classes are defined in the StdCtrls.hpp library.

As we will see in later sections, a list box can be made to allow a user to select more than one item at a time. To support this, the TCustomListBox class is derived from a class named TCustomMultiSelectListControl. To support list-based controls, the VCL provides the TCustomListControl that is the parent of TCustomMultiSelectListControl. Both the TCustomMultiSelectListControl and the TCustomListControl classes are defined in the Controls.hpp header file. The TCustomListControl class derives from TWinControl:

TListBox Inheritance

To visuall add a list box to your application, in the Standard section of the Tool Palette, click the TListBox control ListBox and click the form.

To dynamically create a list box, declare a pointer to a TListBox class and use the new operator to allocate memory for the variable. Also, 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. This can be done 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 variable 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;
}
//---------------------------------------------------------------------------

When an application terminates, 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;
}
//---------------------------------------------------------------------------

Practical LearningPractical Learning: Creating Combo Boxes

  1. Design the form as follows:
     
    Solo Musical Instrument Store: Form Design
    Control Caption ColCount FixedxCols Kind Name
    TGroupBox Group Box Item Selection        
    TLabel Label Item Category:        
    Label Label Item Type:        
    TListBox List Box         lbxItemsCategories
    TListBox List Box         lbxItemsTypes
    TGroupBox Group Box Available Items        
    TStringGrid TStringGrid   3 0   grdAvailableItems
    TBitBtn TBitBtn       bkClose  
  2. Save all

Characteristics of a List Box

 

Introduction

After adding a list box to 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.

If you are programmatically creating the control, you can specify its Windows characteristics as you see fit. Here is an example:

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

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.

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.

Adding an Item to the List

The most fundamental and the most obvious aspect of a list box is the list of items it contains. To support the list of items of this control, the TCustomListBox class is equipped with a property named Items, which is of type TStrings:

__property Classes::TStrings * Items = {read=FItems,write=SetItems};

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 and the item as argument. 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)
{
	Listing->Items->Add(L"C++Builder");
	Listing->Items->Add(L"Delphi");
	Listing->Items->Add(L"JBuilder");
	Listing->Items->Add(L"Kylix");
}
//---------------------------------------------------------------------------

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(Listing->Handle, LB_ADDSTRING, 0, (LPARAM)(L"Edem Kodjo"));
}
//---------------------------------------------------------------------------

The items of a list box are UnicodeString objects created from the TStrings class. This allows you to use the properties of the TStrings class.

The Columns of a List Box

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. To support this, the TCustomListBox class provides the Columns property:

__property int Columns = {read=FColumns,write=SetColumns};

By default, the Columns value is set to 0, which means the items appear in one column.

Adding a Horizontal Scroll Bar to the Control

During introduction, we saw that if a List Box includes more items than the vertical size, which is the Height property, 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 (Listing->Handle, LB_SETHORIZONTALEXTENT, 200, 0);
}
//---------------------------------------------------------------------------

The Index of an Item

When the items have been added to a list box, they (the items) are managed through the TStrings class. In the list box, each item holds a position, also called its index, which is an integral. The index of the first item from top has a value of 0; the second item from top has an index of 1, and so on. To recognize the index of an item, the TCustomListControl class provides the ItemIndex property:

__property int ItemIndex = {read=GetItemIndex,write=SetItemIndex};

The TCustomListControl::ItemIndex is a property that identifies which item is selected in a list-based control. 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. If no item is availble in the list, the TCustomListControl::ItemIndex has a value of Ė1.

Inserting an Item in the List

As opposed to adding an item to the (end of the) list box, you can insert a new item at a certain position. To do this, you can call the Insert() method of the TStrings class. For example, to insert an item in the 2nd position you can write code such as:

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

Selecting an Item

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.  This is done by assign the item's index to the ItemIndex property. For example, 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. Embarcadero RAD Studio 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.

To get a dialog box that makes it easy to exchange items between two list boxes, display the New Items dialog box and select Dual List Box:

New Items

After clicking OK, you would receive a dialog box with two list boxes and all the code would be written for you:

Choices Dialog

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:

__property bool Selected = {read=GetSelected,write=SetSelected};
 
 
 

Selecting Multiple Items

By default, the user can select only one item in the list. The enhance this aspect, the TCustomListBox is equipped with a property named ExtendedSelect:

__property bool ExtendedSelect = {read=FExtendedSelect,write=SetExtendedSelect};

The TCustomListBox::ExtendedSelect property is used in combination with the MultiSelect: of the TCustomMultiSelectListControl class:

__property bool MultiSelect = {read=FMultiSelect,write=SetMultiSelect};

Both properties are represented in the Object Inspector. The default value of the ExtendedSelect property is True but the default value of the MultiSelect property is False.

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 TCustomMultiSelectListControl::SelCount to find out the number of items that the user would have selected:

__property int SelCount = {read=GetSelCount};

Sorting the List

When the items of a list box appear in alphabetical, numerical, or chronological order, the list is said to be sorted. By default, the items of a list box are not sorted. To let you arrange the list, the TCustomListBox class is equipped with a Boolean property named Sorted:

__property bool Sorted = {read=FSorted,write=SetSorted};

 During design, you can use the Objects Inspector to specify the value of this property. As a Boolean data type, you can also set the sorting feature programmatically as follows:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	Listing->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 that item 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.

Custom List Boxes

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.

Removing an Item From the List

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();
}
//---------------------------------------------------------------------------

Practical LearningPractical Learning: Implementing a List Box

  1. Double-click an empty area of the form to generate its OnLoad event
  2. Implement it as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmMusicalStore::FormCreate(TObject *Sender)
    {
    	grdAvailableItems->ColWidths[0] = 50;
    	grdAvailableItems->ColWidths[1] = 270;
    	grdAvailableItems->ColWidths[2] = 60;
    
    	grdAvailableItems->Cells[0][0]  = L"Item #";
    	grdAvailableItems->Cells[1][0]  = L"Item Name/Description";
    	grdAvailableItems->Cells[2][0]  = L"Unit Price";
    
    	// Get a reference to the root node
    	IXMLNode *nodRoot = xdcStoreItems->DocumentElement;
    	// Get a list of the child nodes of the root
    	IXMLNodeList *StoreItems = nodRoot->ChildNodes;
    
    	// Check if the list of node is not empty
    	for(int i = 0; i < StoreItems->Count; i++)
    	{
    		// If some nodes were found, add the items categories to the first list box,
    		// but avoid duplicates
    		if( lbxItemsCategories->Items->IndexOf(StoreItems[0].Get(i)->ChildNodes->Get(1)->Text) <= -1 )
    			lbxItemsCategories->Items->Add(StoreItems[0].Get(i)->ChildNodes->Get(1)->Text);
    	}
    }
    //---------------------------------------------------------------------------
  3. Return to the form
  4. Double-click the left list box
  5. Implement its event as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmMusicalStore::lbxItemsCategoriesClick(TObject *Sender)
    {
    	IXMLNode *nodRoot = xdcStoreItems->DocumentElement;
    	// Get a list of the child nodes of the root
    	IXMLNodeList *StoreItems = nodRoot->ChildNodes;
    
    	// Delete everything in the items types list box
    	lbxItemsTypes->Clear();
    
    	for(int i = 0; i < StoreItems->Count; i++)
    	{
    		if( StoreItems[0].Get(i)->ChildNodes->Get(1)->Text == lbxItemsCategories->Items->Strings[lbxItemsCategories->ItemIndex])
    		{
    			if( lbxItemsTypes->Items->IndexOf(StoreItems[0].Get(i)->ChildNodes->Get(2)->Text) <= -1 )
    				lbxItemsTypes->Items->Add(StoreItems[0].Get(i)->ChildNodes->Get(2)->Text);
    		}
    	}
    }
    //---------------------------------------------------------------------------
  6. Return to the form
  7. Double-click the right list box
  8. Implement its event as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmMusicalStore::lbxItemsTypesClick(TObject *Sender)
    {
        IXMLNode *nodRoot = xdcStoreItems->DocumentElement;
        // Get a list of the child nodes of the root
        IXMLNodeList *StoreItems = nodRoot->ChildNodes;
    
        // Empty the string grid
        for(int a = 0; a < grdAvailableItems->ColCount; a++)
    	for(int b  = 1; b < grdAvailableItems->RowCount; b++)
    		grdAvailableItems->Cells[a][b] = L"";
    
        int EmptyIndex = 1;
    
        for(int i = 0; i < StoreItems->Count; i++)
        {
    	if( (StoreItems[0].Get(i)->ChildNodes->Get(1)->Text == lbxItemsCategories->Items->Strings[lbxItemsCategories->ItemIndex]) &&
    	    (StoreItems[0].Get(i)->ChildNodes->Get(2)->Text == lbxItemsTypes->Items->Strings[lbxItemsTypes->ItemIndex]) )
    	{
    	    if( grdAvailableItems->Cells[0][EmptyIndex] == L"" )
    	    {
    		grdAvailableItems->Cells[0][EmptyIndex] = StoreItems[0].Get(i)->ChildNodes->Get(0)->Text;
    		grdAvailableItems->Cells[1][EmptyIndex] = StoreItems[0].Get(i)->ChildNodes->Get(3)->Text;
    		grdAvailableItems->Cells[2][EmptyIndex] = StoreItems[0].Get(i)->ChildNodes->Get(4)->Text;
    	    }
    
    	    EmptyIndex++;
    	}
        }
    }
    //---------------------------------------------------------------------------
  9. Save all
  10. Press F9 to execute the application to test it
     
    Musical Instrucment Store
     
    Musical Instrucment Store
     
    Musical Instrucment Store
  11. Close the form and return to your programming environment

Introduction to Checked List Boxes

 

Description

A checked list box is a List Box whose items are each equipped with a check box:

Customize

A checked list box combines the functionalities of the List Box and the check box. As a list box, it displays each of its items on a line. If there are too many items than the control can display, it would be equipped with a vertical scroll bar. As described for the list box, if at least one of the items is wider than the control's width, you can make the list box display a horizontal scroll bar.

Creating a Checked List Box

A checked list box control is based on the TCheckListBox class. To provide a checked list box, from the Additional tab of the Tool Palette, click the TCheckListBox button TCheckListBox and click the form or container that would host the control. To programmatically create this control, you can use its constructor. Specify the control owner and its parent. All of the functionality of the checked list box control is provided though its properties.

Characteristics of a Checked List Box

 

Introduction to the Items of a Checked List Box

Like the regular list box, the items of a checked list box are UnicodeString strings controlled by a TStrings property called Items. At design time, to create a list of items and add it to the control, open the String List Editor dialog box, add the necessary strings, and click OK. Of course, you can add the strings at run time, using the Items::Add() method.

When you create the list, the items are stored in the same order you entered them, if you want, you can rearrange them alphabetically or numerically. This can be done by setting the Boolean value of the Sorted property accordingly. As described for the list box, if you set it to true, the items of the checked list box would be sorted. If you set it back to false, the items of the list box would not go back to the way they were but new items would be added at the end of the list.

If you provide a longer list than the control's height can display, it would have a vertical scroll bar. If just one or a few items are hidden by the scroll bar, you can heighten it if the form provides more space. Alternatively, you can also create the list in various columns. To do this, set the value of the Columns property to a number of your choice. Normally, the number of columns should not exceed 5 or this would indicate that you may simply need more than one checked list box control:

If at least one of the items is wider than the width of the control, you have various alternatives. You can display a horizontal scroll bar by calling the Win32 API SendMessage() function and specifying the LB_SETHORIZONTALEXTENT value as the message to send:

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

Using a Checked List Box

To select an item in the list, the user can click the desired string. Unlike the regular list box, the user cannot select more than one string in the list. For this reason, if you desire a normal list of objects, use the regular list box control.

When the user clicks the check box of an item, the checked list box fires an OnClickCheck event. You can use this event to take some action. The OnClickCheck event of a TNotifyEvent type and therefore specifies only the Sender of the event.

The most important and obvious characteristic of the checked list box is that each item displays a check box on its left. This box allows the user to select or deselect each item. To select an item, the user must click its box and not its string, to indicate an explicit selection. This draws a check mark in the box. As described with the check box, the user can deselect a string by removing the check mark. The check mark indicates that an item is selected and the absence of the check mark indicates the contrary. Like the check box, you can allow the user to indicate a "half-checked" item. In this case, a check box can appear unchecked, checked, or grayed.

Flat Check Boxes

After creating the list, each item appears with a flat check box to its left. This detailt is controlled by the Boolean Flat property:

__property bool Flat = {read=FFlat,write=SetFlat};

If you want a 3-D check box, you can change the Flat property from its true default to a false value.

Introduction to the Header of a Checked List Box

You can also resize the control to make it wider to accommodate the large item. After creating the list, sorted or not, each item has a positional index that allows you to access it. The array of this index can have a different name depending on why you want to access it. For example, the items are stored in an array called Header:

__property bool Header = {read=GetHeader,write=SetHeader};

Each item can be accessed using the Header[Index] array. The Header index is used if you want an item to be distinct from the others. To do this, at run time, access that item Header index and set its Header Boolean property to true. To distinguish the header item from the others, it uses a different text color and it does not display a check box. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
	CheckListBox1->Header[2] = True;
}
//---------------------------------------------------------------------------

You can make more than one item appear as Header.

The Background Color of a Header

The Header item displays a color represented by the HeaderBackgroundColor property:

__property Graphics::TColor HeaderBackgroundColor = 
{
    read=FHeaderBackgroundColor,
    write=SetHeaderBackgroundColor
};

The Text Color of a Header

The text of the Header item displays in a color known as the HeaderColor property:

__property Graphics::TColor HeaderColor = {read=FHeaderColor,write=SetHeaderColor};

You can set these values to any valid color you want.

The Checked Items

The items of a checked list box are stored in an array called Checked:

__property bool Checked = {read=GetChecked,write=SetChecked};

The first or top item of a checked list box has an index of 0 and can be accessed with Checked[0]. The second item has an index of 1 and can be accessed with Checked[0], etc. As stated already, to select an item, the user clicks its check box. To find out if an item has been checked, access its Checked index and check whether it is true or false. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::CheckListBox1Click(TObject *Sender)
{
	if( CheckListBox1->Checked[1] == True )
		ShowMessage(L"Welcome to Montgomery County!");
}
//---------------------------------------------------------------------------

A Grayed Checked Item

To increase the options of the checked list box, you can let the user "half-Select" an item or indicate when an item is not completely selected and not completely deselected. Such an item is referred to as grayed. This is controlled by the AllowGrayed Boolean property:

__property bool AllowGrayed = {read=FAllowGrayed,write=FAllowGrayed};

The State of an Item

If a checked list box control has this property on, to check the appearance of a check mark or absence of it on an item, use the State property:

__property Stdctrls::TCheckBoxState State = {read=GetState,write=SetState};

The value of this property is an enumeration type defined as follows:

enum TCheckBoxState
{
    cbUnchecked,
    cbChecked,
    cbGrayed
};
  • If an item is checked, its State has a value of cbUnchecked
  • If an item is clearly checked, its State has a value of cbChecked
  • If an item is undecided, that is, if it is grayed, its State has a value of cbGrayed

The check mark appearance of the items of a checked list box control are stored in an array called State. To find out the check mark or lack of it of an item, call the State property and specify the index of the desired item. The following checks whether a check mark appears on the 5th item of the list:

//---------------------------------------------------------------------------
void __fastcall TForm1::CheckListBox1Click(TObject *Sender)
{
	if( CheckListBox1->State[4] == cbChecked )
		ShowMessage(L"The Bay Bridge is closed.\nYou can't get to Annapolis!!!");
}
//---------------------------------------------------------------------------

Enabling of Disabling an Item

If for any reason you do not want the users to be able to select items, only to view the list, you can set the Enabled property of the control to false. On the other hand, if you want to disable only one or a few items, you can do that. The items of a checked list box are stored in an array called ItemEnabled:

__property bool ItemEnabled = {read=GetItemEnabled,write=SetItemEnabled};

To enable or disable an item, call this property and specify the index of the item you want to enable or disable. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
	CheckListBox1->ItemEnabled[2] = False;
	CheckListBox1->ItemEnabled[4] = False;
	CheckListBox1->ItemEnabled[5] = False;
}
//---------------------------------------------------------------------------
 
 
   
 

Home Copyright © 2010-2011 FunctionX, Inc.