Sign in Join
Wiki copytemporary

TDBLookupComboBox: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: TDBLookupComboBox

OldNewLine
1+**TDBLookupComboBox** ![](/wiki-images/4/46/Tdblookupcombobox.png) is a (doubly) data-bound [[TComboBox]]. A TDBLookupComboBox can be found on the [[Data Controls tab]] of the [[Component Palette]].
2+
3+The TDBLookupCombobox control gets a list of values from its *ListSource* (which e.g. represents a table with product info, "Products"). It then:
4+
5+- displays the values in the **ListField** (e.g. a "ProductName" field) while
6+- remembering the values in the **KeyField** (e.g. an "ID" field)
7+
8+The combobox stores the result (i.e. the **KeyField** value in the **DataField**, e.g. the "ProductID" field in the **DataSource** property (e.g. an "Orders" table).
9+
10+The difference with the [[TDBComboBox]] is that the TDBComboBox is a (as it were) "singly data bound control": it stores the results in a database field but the list of values to select from is supplied by code/via the [[Object Inspector]].
11+
12+## Unbound use
13+
14+You can get the combobox to look up values from one table without storing the results in another by leaving the *DataSource* and the *KeyField* properties empty.
15+
16+The following sample code snippet will:
17+
18+- Allow a TDBLookupCombo box to be configured in unbound mode (i.e. no changes made to any table in the database)
19+- Ensure the visible data in the TDBLookupComboBox is from the selected record in the dataset (i.e. choosing a new value in TDBLookupComboBox contents will scroll the dataset to the correct record)
20+- Set the initial displayed value in the TDBLookupComboBox and the selected record in the datset to previously remembered values.
21+
22+The following sample code snipper will NOT:
23+
24+- Automatically update the TDBLookupComboBox value if the dataset is scrolled (you need to add your own handler to Dataset.OnScroll to achieve this)
25+
26+``` pascal
27+interface
28+ type
29+ TForm1 = class(TForm)
30+ cboLookup: TDBLookupComboBox;
31+ dsSource: TDatasource;
32+ dsetSource: TDataset;
33+ ...
34+ protected
35+ FDisplayField: string;
36+ FKeyField: string;
37+ FPreviousKeyValue: string; // May be any datatype - see below
38+ ...
39+ end;
40+
41+...
42+
43+implementation
44+
45+...
46+ // Remember previous value
47+ FPreviousKeyValue:= load_from_settings_in_your_preferred_way_;
48+
49+...
50+ // Configure DBLookupCombo
51+ dsSource.Dataset := dsetSource;
52+ cboLookup.ListSource := dsSource;
53+
54+ cboLookup.ScrollListDataset := True; // This ensures that changing the ComboBox will automatically scroll
55+ // the dataset
56+ cboLookup.Style := csDropDownList;
57+
58+ cboLookup.KeyField := FKeyField;
59+ cboLookup.ListField := FDisplayField; // This is the field that will appear in the contents of the ComboBox
60+
61+ dsetSource.Open; // The ComboBox should now be populated, however intially no text is displayed
62+ // So right now there is no relationship between the selected record in the dataset
63+ // and the contents of the ComboBox
64+
65+ // cboLookup.KeyValue reads and writes a Variant, so you may actually define
66+ // FPreviousKeyValue as any data type you feel is appropriate.
67+
68+ // Remember a previous value
69+ if FPreviousKeyValue <> '' then
70+ begin
71+ dsetSource.Locate(FKeyField, FPreviousKeyValue, []); // Note: This will fail to correctly set the ComboBox,
72+ // But will set the Datatset to the correct record.
73+
74+ // Now the dataset is on the correct record, lets ensure the DBLookupCombo
75+ // is showing the same value as the selected record
76+ If (cboLookup.KeyValue = Null) And (dsetSource.RecordCount > 0) Then
77+ cboLookup.KeyValue := dsetSource.FieldByName(FKeyField).AsVariant;
78+ end;
79+
80+...
81+ // Save current value for next time
82+ FPreviousKeyValue:= cboLookup.KeyValue;
83+ write_to_settings_in_your_preferred_way_(FPreviousValue);
84+```
85+
86+## Bugs
87+
88+At least for TDBLookupComboBox, there is a bug with FPC 2.6.0 (used in Lazarus 1.0, 1.0.2 etc) that requires the **listfield** to be present in the datasource as well.
89+
90+Workaround: you can bypass this by declaring a calculated field with the same name as the listfield in the datasource's dataset that does nothing.
91+
92+## Alternative control
93+
94+The Rx controls (in the RxNew package) have the RxDBLookupCombobox which has some extra functionality; it e.g. allows to display multiple fields/columns next to each other (much like MS Access comboboxes):
95+
96+``` pascal
97+RxDBLookupCombo.LookupDisplay = 'field1;field2'; //takes a semicolon-delimited list of fields
98+```
99+
100+It additionally has a property DisplayAllFields.
101+
102+## See also
103+
104+- [[doc:lcl/dbctrls/tdblookupcombobox.html|TDBLookupComboBox doc]]
105+- [[TComboBox]]
106+- [[TDBComboBox]]
107+
108+---
109+*From the Free Pascal wiki, page "TDBLookupComboBox", as it stood on 2020-02-29 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history