Assuming you have a TStringList containing name/value pairs, and you want a TComboBox showing just the Values, while being able to get the selected key:
This will setup the values in the TComboBox:
procedure ComboBoxSetValues(AComboBox: TCustomComboBox; AStrings: TStrings);
var LIndex: integer;
begin
AComboBox.Clear;
AComboBox.Tag := PtrInt(AStrings);
for LIndex := 0 to AStrings.Count - 1 do begin
AComboBox.Items.Add(AStrings.ValueFromIndex[LIndex]);
end;
end;
And, this will return the selected key:
function ComboBoxGetSelectedKey(AComboBox: TComboBox): string;
begin
if AComboBox.ItemIndex < 0 then begin
Result := EmptyStr;
end else begin
Result := (TObject(AComboBox.Tag) as TStrings).Names[AComboBox.ItemIndex];
end;
end;
Call ComboBoxSetValues() in the TComboBox.OnGetItems event, and ComboBoxGetSelectedKey() in TComboBox.OnSelect.
I have a feeling I know what you were hoping for. As far as I can tell, there is no way to intercept access to the internal TStrings class. At line 856 of customcombobox.inc a TStringListUTF8Fast is created with no way to intercept. There is also no way to intercept FItems access either, since all code accesses the private FItems field directly or the via Items property (indirectly). Ideally, the class would provide a virtual CreateStings method with which you could override and provide your own magic TStrings derived class.
On top of that, TString's doesn't provide a way to intercept access either. It provides a 'get' abstract method, which TStringList thens overides and access its private Flist^[Index].FString data. ie: No way to intercept to filter strings.
So, no, I dont see a way to intercept item access to filter what actually gets shown in the TComoBox. That said, you can use ownerdraw, which is what TComboBoxEx does, but then you are limited to csOwnerDrawFixed. Which means, no more text selection editing.
If you look in TCustomComboBox.DrawItem, you find a call to InternalDrawItem. You can copy InternalDrawItem out, write your own super class and change the call from:
InternalDrawItem(Self, FCanvas, ARect, Items[Index])
to
InternalDrawItem(Self, Canvas, ARect, ValueFromIndex[Index])
This creates a TComboBox class which will display only the Values of the internal Items. But, again, no editing.
I don't see a clean solution to create filtered TComboBox.Items, without adding a virtual CreateStings method. I'm sure I can come up with more hackery. But thats all I have ATM.
Feature request? A CreateStings() method with matching OnCreateStrings for TCustomComboBox?