Subject Re: [IBO] IB_ComboBox
Author Helen Borrie
At 07:10 PM 12/08/2005 +0000, you wrote:
>I couldnĀ“t find ItemIndex property in IB_Combobox, as with TComboBox,
>indicating which item in the drop-down list is selected.

It's there; but it is exposed as a read-only property, since TIB_Combobox
is a data-aware control - meaning that the current value in the field that
is linked to the control's index value determines what value belongs there.

>I missed too the event OnSelect, which oOccurs in TComboBox when the
>user selects a string in the drop-down list.

But TComboBox is not a data-aware control! If you don't want your selector
box to be data-aware, use TComboBox.

>How is it possible to know when and what element was selected by user
>in IB_Combobox?

You can read the latest value in the dataset field that the control's
DataField property points to. That's the point of a data-aware control.

Another option open to you is to use the control's ItemValues property,
with Style set to csDropDownList. This is very useful in the situation
where the value that the control is linked to is different to the value
that the user selects. In ItemValues, place the values that you want to
store into the corresponding ItemValues[] item. Then, when the user makes a
selection, the user sees e.g. a meaningful string, while the less
user-friendly number is taken from ItemValues[] and written to the linked
field.

Here's an example of loading an ib_combobox at FormCreate time, with Style
set to csDropDownList:

var
i: integer;
DayText: string;
begin
....
for I := 1 to 7 do
begin
cbxDOW.ItemValues.Add(IntToStr(i + 1));
case i of
1: DayText := 'Sunday';
2: DayText := 'Monday';
.............
7: DayText := 'Saturday';
end;
cbxDOW.Items.Add(DayText);
end;
end;

Of course, you can also load the Items and ItemValues arrays manually at
design time. However, the technique above can be used to load your Items
and ItemValues from a query. Let's suppose your database stores bank names
in a table, along with a unique internal key. You want to show the bank
name to the user and have the application refer to the unique key.

Place a query to the Banks table in an ib_cursor:

ibcBanks.SQL.Add('select BankID, BankName from Banks');

Then, load up the control at FormCreate (or, if you need to, inside a
procedure that you can call at FormCreate but also at other times, in case
you want to refresh the offerings):

begin
with ibcBanks, cbxBanks do
begin
if not IB_Transaction.Started then
IB_Transaction.StartTransaction;
try
Items.Clear;
ItemValues.Clear;
First; // open the ib_cursor
while not EOF do
begin
Items.Add(FieldByName('BankName').AsString);
ItemValues.Add(FieldByName('BankID').AsString);
Next; // move to the next record
end;
finally
IB_Transaction.Commit;
Close;
Unprepare;
end;
end;
end;

I always use a specific transaction for these loads, that I keep just for
the purpose of accessing and updating this kind of "static" data. If you
are using several ib_comboboxes with a number of (ID, Description) sets in
this way, write your procedure so that it is generic: pass the particular
ib_cursor as an argument to the procedure and refer to the fields by their
field indexes instead of ByName.

Something that might not have made itself obvious to you yet is that
data-aware controls are "aware" of one field in one dataset. TIB_ComboBox
is such a control. DataSource and DataField refer to the parent dataset's
IB_Datasource and controlling field, respectively.

IBO also has a "double data aware" control, TIB_LookupCombo. In essence,
the dropdown part of this control is data-aware as well - the dropdown part
of the control is dynamically linked to a query and stays linked. Using it
is a little more complex. There is a walk-through in the TI sheet "Working
with IBO Data-aware Controls" which you can download from the Tech Info
page at the main IBO website.

Helen