Thursday, November 7, 2019
Store a String Along With a String in Delphis ListBox
Store a String Along With a String in Delphis ListBox Delphis TListBox and TComboBox display a list of items - strings in a selectable list. TListBox displays a scrollable list, the TComboBox displays a drop-down list. A common property to all the above controls is the Items property. Items define a list of strings that will appear in the control to the user. At design-time, when you double-click the Items property, the String List Editor lets you specify string items. The Items property is actually a TStrings type descendant. Two Strings Per Item in a ListBox? There are situations when you want to display a list of strings to the user, for example in the list box control, but also have a way to store one more additional string along the one displayed to the user. Whats more, you might want to store/attach more than just a plain string to the string, you might want to attach an object to the item (string). ListBox.Items - TStrings Knows Objects! Give the TStrings object one more look in the Help system. Theres the Objects property which represents a set of objects that are associated with each of the strings in the Strings property - where the Strings property references the actual strings in the list. If you want to assign a second string (or an object) to every string in the list box, you need to populate the Items property at run-time. While you can use the ListBox.Items.Add method to add strings to the list, to associate an object with each string, you will need to use another approach. The ListBox.Items.AddObject method accepts two parameters. The first parameter, Item is the text of the item. The second parameter, AObject is the object associated with the item. Note that list box exposes the AddItem method which does the same as Items.AddObject. Two Strings for One String Since both Items.AddObject and AddItem accept a variable of type TObject for their second parameter, a line like: //compile error! ListBox1.Items.AddObject(zarko, gajic); will result in a compile error: E2010 Incompatible types: TObject and string. You cannot simply supply a string for the object since in Delphi for Win32 string values are not objects. To assign a second string to the list box item, you need to transform a string variable into an object - you need a custom TString object. An Integer for a String If the second value you need to store along with the string item is an integer value, you actually do not need a custom TInteger class. ListBox1.AddItem(Zarko Gajic, TObject(1973)) ; The line above stores the integer number 1973 along with the added Zarko Gajic string. A direct typecast from an integer to an object is made above. The AObject parameter is actually the 4-byte pointer (address) of the object added. Since in Win32 an integer occupies 4 bytes - such a hard cast is possible. To get back the integer associated with the string, you need to cast the object back to the integer value: //year 1973 year : Integer(ListBox1.Items.Objects[ListBox1.Items.IndexOf(Zarko Gajic)]) ; A Delphi Control for a String Why stop here? Assigning strings and integers to a string in a list box is, as you just experienced, a piece of cake. Since Delphi controls are actually objects, you can attach a control to every string displayed in the list box. The following code adds to the ListBox1 (list box) captions of all the TButton controls on a form (place this in the forms OnCreate event handler) along with the reference to each button. var à à idx : integer; begin à à for idx : 0 to -1 ComponentCount do à à begin à à à à if Components[idx] is TButton then ListBox1.AddObject(TButton(Components[idx]).Caption, Components[idx]) ; à à end; end; To programmatically click the second button, you can use the next statement: TButton(ListBox1.Items.Objects[1]).Click; I Want to Assign My Custom Objects to the String Item In a more generic situation you would add instances (objects) of your own custom classes: type à à TStudent class à à private à à à à fName: string; à à à à fYear: integer; à à public à à à à property Name : string read fName; à à à à property Year : integer read fYear; à à à à constructor Create(const name : string; const year : integer) ; à à end; ........ constructor TStudent.Create(const name : string; const year : integer) ; begin à à fName : name; à à fYear : year; end; begin à à //add two string/objects - students to the list à à ListBox1.AddItem(John, TStudent.Create(John, 1970)) ; à à ListBox1.AddItem(Jack, TStudent.Create(Jack, 1982)) ; à à //grab the first student - John à à student : ListBox1.Items.Objects[0] as TStudent; à à //display Johns year à à ShowMessage(IntToStr(student.Year)) ; end; What You Create You Must Free Heres what the Help has to say about objects in TStrings descendants: the TStrings object does not own the objects you add this way. Objects added to the TStrings object still exist even if the TStrings instance is destroyed. They must be explicitly destroyed by the application. When you add objects to strings - objects that you create - you must make sure you free the memory occupied, or youll have a memory leak A generic custom procedure FreeObjects accepts a variable of type TStrings as its only parameter. FreeObjects will free any objects associated with an item in the string list In the above example, students (TStudent class) are attached to a string in a list box, when the application is about to be closed (main form OnDestroy event, for example), you need to free the memory occupied: FreeObjects(ListBox1.Items) ; Note: You only call this procedure when objects assigned to string items were created by you.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.