ST3VO
asked on
Working with 2 ComboBoxes
Hi all,
I have a comboBox with a list of Car Makes....
Now what I need to do is for example:
If I choose FORD for ComboBox1 then display a list of FORD models etc...
I have all the Data and I don't mind hardcoding it...(No Database for this please).
E.g:
ComboBox1 ComboxBox2
FORD Fiesta
etc
etc
Hope you can help!
THanks
ST3VO
I have a comboBox with a list of Car Makes....
Now what I need to do is for example:
If I choose FORD for ComboBox1 then display a list of FORD models etc...
I have all the Data and I don't mind hardcoding it...(No Database for this please).
E.g:
ComboBox1 ComboxBox2
FORD Fiesta
etc
etc
Hope you can help!
THanks
ST3VO
Code correction. See new code below:
procedure TForm1.ComboBox1CloseUp(Sender: TObject);
begin
if Combobox1.Text = 'FORD' then
begin
Combobox2.Items.Clear;
Combobox2.Items.Add('FORD MODEL 1');
Combobox2.Items.Add('FORD MODEL 2');
Combobox2.Items.Add('FORD MODEL 3');
end;
end;
this is an example of doing it 'semi automated':
procedure TForm2.ComboBox1Change(Sender: TObject);
begin
if ComboBox1.ItemIndex <> -1 then
ComboBox2.Items.Assign(TStringList(ComboBox1.Items.Objects[ComboBox1.ItemIndex]));
end;
procedure TForm2.FormCreate(Sender: TObject);
procedure AddItem(Name: string; SubItems: array of string);
var StringList: TStringList;
i: integer;
begin
StringList := TStringList.Create();
for i := 0 to Length(SubItems) - 1 do
StringList.Add(SubItems[i]);
ComboBox1.AddItem(Name, StringList);
end;
begin
AddItem('Ford', ['Fiesta', 'Mondeo', 'Galaxy']);
AddItem('Seat', ['Altea', 'Leon', 'Albrahama']);
end;
procedure TForm2.FormDestroy(Sender: TObject);
var i: integer;
begin
for i := 0 to Combobox1.Items.Count - 1 do
ComboBox1.Items.Objects[1].Free();
end;
You can also do LoadFromFile if you want to store the items in an external file:
If Combobox1.text = 'FORD' then
begin
combobox2.items.clear;
combobox2.Items.LoadFromFi le(extract filepath(A pplication .ExeName) + 'FordModels.txt);
end;
The part "extractfilepath(Applicati on.ExeName )" gives the folder your exe is running from. So you would keep a txt file called "FordModels.text" in your application directory, and experiment with the contents
If Combobox1.text = 'FORD' then
begin
combobox2.items.clear;
combobox2.Items.LoadFromFi
end;
The part "extractfilepath(Applicati
> No Database for this please
what is your definition of a database, something like SQL, or any external file.
Would you prefer hard coding or storing external?
what is your definition of a database, something like SQL, or any external file.
Would you prefer hard coding or storing external?
ASKER
I don't mind external files....But I don't want to connect to a Table....for this...That's what I mean't!
ASKER
I'm testing your's right now MerijnB!
here an example which uses an external file.
The file is called 'cars.dat' and should be located in the directory the application is started.
Here an example of cars.dat:
List=Ford,Seat
Ford=Galaxy,Mondeo,Fiesta
Seat=Leon,Altea,Toledo
The file is called 'cars.dat' and should be located in the directory the application is started.
Here an example of cars.dat:
List=Ford,Seat
Ford=Galaxy,Mondeo,Fiesta
Seat=Leon,Altea,Toledo
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm2 = class(TForm)
ComboBox1: TComboBox;
ComboBox2: TComboBox;
procedure FormCreate(Sender: TObject);
procedure ComboBox1Change(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
fCars: TStringList;
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.ComboBox1Change(Sender: TObject);
begin
if ComboBox1.ItemIndex <> -1 then
ComboBox2.Items.CommaText := fCars.Values[Combobox1.Items[Combobox1.ItemIndex]];
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
fCars := TStringList.Create();
fCars.StrictDelimiter := true;
fCars.LoadFromFile('cars.dat');
ComboBox1.Items.CommaText := fCars.Values['List'];
end;
procedure TForm2.FormDestroy(Sender: TObject);
begin
fCars.Free();
end;
end.
ASKER
Right....
Got a little problem here.
The list of MAKES is about 100
And I am coding it this way:
if sco.Text = 'ASTON MARTIN' then //ASTON MARTIN Models
begin
sModels.items.clear;
sModels.Text:='ANY';
sModels.Items.LoadFromFile ('.\data\M OD\ASTON.d at');;
end;
if sco.Text = 'AUDI' then //AUDI Models
begin
sModels.items.clear;
sModels.Text:='ANY';
sModels.Items.LoadFromFile ('.\data\M OD\AUDI.da t');;
The problem here is that the code is going to be massive!
MerijnB's code also works great but is also going to take me ages to put it together.
Anyone got a suggestion on how the get it done quicker without connecting to a table?
One one side I have the list of 100 Makes and on another file all the Massive list of models.
Any suggestions please?
Thanks
ST3VO
Got a little problem here.
The list of MAKES is about 100
And I am coding it this way:
if sco.Text = 'ASTON MARTIN' then //ASTON MARTIN Models
begin
sModels.items.clear;
sModels.Text:='ANY';
sModels.Items.LoadFromFile
end;
if sco.Text = 'AUDI' then //AUDI Models
begin
sModels.items.clear;
sModels.Text:='ANY';
sModels.Items.LoadFromFile
The problem here is that the code is going to be massive!
MerijnB's code also works great but is also going to take me ages to put it together.
Anyone got a suggestion on how the get it done quicker without connecting to a table?
One one side I have the list of 100 Makes and on another file all the Massive list of models.
Any suggestions please?
Thanks
ST3VO
What was wrong with my suggestion to do loadfromfile?
You store your 100 models in a txt file and use loadfromfile?
I suppose you'd have plenty of if then statements like:
if sco.Text = 'AUDI' then...
if sco.text = 'ASTON MARTIN' then..
So you could call all your txt files the name of your markes, i.e.
AUDI.txt
ASTON MARTIN.txt
Thus you could say:
combobox2.items.clear;
combobox2.Items.LoadFromFi le(extract filepath(A pplication .ExeName) + sco.text + '.txt');
===
Is there any particular reason why you're opposed to tables?
You could use a nice master-detail relationship.
If you're not familiar with that, basically your one table would contain MAKES, the other ***ALL*** the models but with a column for the Make. The *models* table would set the *Make* table as its MasterTable, and its MasterField would be the "Make". Then connect your combo boxes accordingly and it will work automatically !
You store your 100 models in a txt file and use loadfromfile?
I suppose you'd have plenty of if then statements like:
if sco.Text = 'AUDI' then...
if sco.text = 'ASTON MARTIN' then..
So you could call all your txt files the name of your markes, i.e.
AUDI.txt
ASTON MARTIN.txt
Thus you could say:
combobox2.items.clear;
combobox2.Items.LoadFromFi
===
Is there any particular reason why you're opposed to tables?
You could use a nice master-detail relationship.
If you're not familiar with that, basically your one table would contain MAKES, the other ***ALL*** the models but with a column for the Make. The *models* table would set the *Make* table as its MasterTable, and its MasterField would be the "Make". Then connect your combo boxes accordingly and it will work automatically !
ASKER
I already have all the MAKE's inside the ComboBox1 Strings....
I just want to avoid all the If..then's...because I would have 100 If...thens...
I just want to avoid all the If..then's...because I would have 100 If...thens...
ASKER
MerijnB, I'm trying out your latest code now...
ASKER
MerijnB, Cannot use your code because the Database which I need to query after the selection contains fields like:
Models:
AC,544
so, If I separated it by commas it would see model AC,544 and two different models.
Models:
AC,544
so, If I separated it by commas it would see model AC,544 and two different models.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I'll try your's now rfwoolf!
Now, if you do want to use 100 if... then statements, make sure you know about case of statements:
Case sco.text of
'FORD': begin
//
end;
'TOYOTA': begin
//
end;
'ASTON MARTIN': begin
//
end;
--Haven't tested it, but you get the idea
Case sco.text of
'FORD': begin
//
end;
'TOYOTA': begin
//
end;
'ASTON MARTIN': begin
//
end;
--Haven't tested it, but you get the idea
How about a simple INI file.That Looks Like This
[Ford]
Fiesta=
Lincoln=
F150=
Ranger=
[Chevy]
Astro=
Nova=
[Dodge]
Ram=
Charger=
Caravan=
And the following simple code:
[Ford]
Fiesta=
Lincoln=
F150=
Ranger=
[Chevy]
Astro=
Nova=
[Dodge]
Ram=
Charger=
Caravan=
And the following simple code:
procedure TForm1.FormShow(Sender: TObject);
var ini : TiniFile;
begin
ini := TIniFile.Create(ExtractFilePath(Application.ExeName) + 'Cars.ini');
ini.ReadSections(cbMake.Items);
ini.Free;
end;
procedure TForm1.cbMakeCloseUp(Sender: TObject);
var ini : TiniFile;
i : integer;
begin
ini := TIniFile.Create(ExtractFilePath(Application.ExeName) + 'Cars.ini');
ini.ReadSectionValues(cbMake.Text, cbModel.Items);
for i := 0 to cbModel.Items.Count -1 do
cbModel.Items[i] := cbModel.Items.Names[i];
ini.Free;
end;
Then add your first list of items:
FORD,
GM,
TOYOTA
etc
Then you would add a OnCloseUp event handler to ComboBox1. and say something like this:
procedure TForm1.ComboBox1CloseUp(Se
begin
if Combobox1.Text = 'FORD' then
Combobox2.Items.Clear;
Combobox2.Items.Add('FORD MODEL 1');
Combobox2.Items.Add('FORD MODEL 2');
Combobox2.Items.Add('FORD MODEL 3');
end;