working with 2 listboxes

Dear friends,

1. I create two string list editor. Ok?

However in my form would appear an option for which list must be appear (in a combobox) for example.

When the user choice one or another, that list will appear in a combobox. Now the user click one item and appear in a memo the
item of another list in the same line.

In resume: I am wroking with two lists, but only only the user see.
When the user click one item, at side appear a memo with the item (same line) of another list.

Best regards.

janlee
janleeAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

mocartsCommented:
hi, janlee :)

comboBox example (written from head - so there can be compile time or runtime errors, but you can get main idea from this code):

var
  s1, s2: TStringList;

procedure TForm1.FormCreate(Sender: TObject);
begin
  // load comboboxes from string lists
  ComboBox1.Items.Assign(s1);
  ComboBox2.Items.Assign(s2);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  // save items
  s1.Assign(ComboBox1.Items);
  s2.Assign(ComboBox2.Items);
end;

// OnChange for combobox1 (same must be implemented for combobox2)
procedure TForm1.ComboBox1Change(Sender: TObject);
begin
  if (ComboBox1.ItemIndex > -1) and   (ComboBox1.ItemIndex < ComboBox2.Items.Count) then
    Edit1.Lines.Text := ComboBox2.Items[ComboBox1.ItemIndex]
  else
    Edit1.Lines.Text := '< unassigned >';
  Edit1.Tag := integer(ComboBox2); // current edited combobox items
end;

procedure TForm1.Edit1Exit(Sender: TObject);
begin
  // save current item changes, if any
  if Edit1.Modified and (Edit1.Tag <> 0) and (TComboBox(Edit1.Tag).ItemIndex > -1) then
  begin
    TComboBox(Edit1.Tag).Items[TComboBox(Edit1.Tag).ItemIndex] := Edit1.Text;
    Edit1.Modified := False;
  end;
end;

wbr, mo.
0
roknjohnCommented:
1) are you using two TListBox controls and toggling their visiblity depending on the user's selection in the TComboBox, or are you using just one TListBox and loading its contents based on the TComboBox selection?

2) Are you saying that you DO or DO NOT want the string from the other list to display in the memo?

If you post your code, we can help you much faster.
0
janleeAuthor Commented:
Please, there are misspellings in your script such as

Edit1.Lines.Text
2 formcreate

jl
0
Angular Fundamentals

Learn the fundamentals of Angular 2, a JavaScript framework for developing dynamic single page applications.

roknjohnCommented:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    ComboBox1: TComboBox;
    ListBox1: TListBox;
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure ComboBox1Change(Sender: TObject);
    procedure ListBox1Click(Sender: TObject);
    procedure Edit1Change(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    List1, List2 : TStringList;  //these are your lists to edit
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  List1 := TStringList.Create;
  List2 := TStringList.Create;

  //Populate the lists from somewhere, like:
  List1.LoadFromFile('C:\List1.txt');
  List2.LoadFromFile('C:\List2.txt');

  //Populate the combobox, is not done at design time
  ComboBox1.Items.Add('List 1');
  ComboBox1.Items.Add('List 2');
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  List2.Free;   //You'll probably want to save these lists before freeing them.  
  List1.Free;  //Do that in a button OnClick or the forms OnClose event
end;

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
  case ComboBox1.ItemIndex of                  //show the selected list
    0 : ListBox1.Items.Assign(List1);
    1 : ListBox1.Items.Assign(List2);
  end;
end;

procedure TForm1.ListBox1Click(Sender: TObject);
begin
  case ComboBox1.ItemIndex of                     //show the correlated item of the selected item in the edit box
    0 : Edit1.Text := List2[ListBox1.ItemIndex];
    1 : Edit1.Text := List1[ListBox1.ItemIndex];
  end;
end;

procedure TForm1.Edit1Change(Sender: TObject);
begin
  case ComboBox1.ItemIndex of                          //update the list of any user changes to the item
    0 : List2[ListBox1.ItemIndex] := Edit1.Text;
    1 : List1[ListBox1.ItemIndex] := Edit1.Text;
  end;
end;

end.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
janleeAuthor Commented:
Dear RockHohn,

Congratulations. Your script works very, very fine.

However my intention is hidden the source of data, in this way I was thought in use the ´string list editor´ . Would be possible using
your unique combobox create a stringlist in this way:

ONE,UNO
TWO,DEUX
THREE,TROIS
FOUR,CATRE
FIVE,CINQUE

Where the words before the comma would be ´list1´ and words after comma would be ´list2´.

I will put more points.

Many thanks.

janlee


You win
0
janleeAuthor Commented:
Dear RockJohn,

I forgot to mention there is a problem with your script. A little problem.
The lists are not indexed. It is possible? I  know it is possible sort the items of a listbox, however and in another list?

regards,

jl
0
roknjohnCommented:
janlee,

It is fairly easy to split an input file of:

ONE,UNO
TWO,DEUX
THREE,TROIS
FOUR,CATRE
FIVE,CINQUE

into 2 stringlists of ONE, TWO..FIVE and UNO, DEUX, CINQUE.

procedure LoadLists(InputFile : string; List1, List2 : TStringList);
var
  i, p : integer;
  s : string;
begin
  List2.LoadFromFile(InputFile);
  List1.Clear;
  for i := 0 to List2.Count-1 do begin
    s := List2[i];
    p := Pos(',',s);
    List1.Add(Copy(List2[i],1,p-1));
    Delete(s,1,p);
    List2[i] := s;
  end;
end;
0
roknjohnCommented:
janlee,

About indexing.  If you need to sort one or both of the lists while preserving the relationship between the items, you can use the Objects property, and store the original index value, typecast as a pointer.

After the lists are loaded, do something like:

  for i := 0 to List1.Count-1 do begin
    List1.Objects[i] := Pointer(i);
    List2.Objects[i] := Pointer(i);
  end;

Then, change the following event handlers to look like:

procedure TForm1.ListBox1Click(Sender: TObject);
var
  ix : Pointer;
begin
  ix := ListBox1.Items.Objects[ListBox1.ItemIndex];
  case ComboBox1.ItemIndex of
    0 : Edit1.Text := List2[List2.IndexOfObject(ix)];
    1 : Edit1.Text := List1[List1.IndexOfObject(ix)];
  end;
end;

procedure TForm1.Edit1Change(Sender: TObject);
var
  ix : Pointer;
begin
  ix := ListBox1.Items.Objects[ListBox1.ItemIndex];
  case ComboBox1.ItemIndex of
    0 : List2[List2.IndexOfObject(ix)] := Edit1.Text;
    1 : List1[List1.IndexOfObject(ix)] := Edit1.Text;
  end;
end;

Now you can sort either list.  Hope this helps.
0
janleeAuthor Commented:
Ok. Now it is working very, very fine.

Thank you very much.

Best Regards.

janlee
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.