nosx
nosx

Reputation: 145

update TEdit text from combobox

I have a form that consist of two TComboBox and one TEdit controls and I would like to be able to update a word in the TEdit control with the value from the comboboxes, but not quite sure how to make it work.

Example:

Combobox #1 has the following items: sue, bill, andy, chris

Combobox #2 has the following items: 1, 2, 3

The TEdit control starts out looking something like this: andy has 3 cars

Now, what I want to do is to be able to change the word andy with the currently selected item in combobox #1 and the number 3 with the currently selected item in combobox #2, but I just cannot seem to wrap my head around how to accomplish this and thought I would come to the experts for a little advise.

Upvotes: 1

Views: 3862

Answers (1)

Andreas Rejbrand
Andreas Rejbrand

Reputation: 108948

Assign the same event hander to both combo boxes' OnChange event:

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
  Edit1.Text := ComboBox1.Text + ' has ' + ComboBox2.Text + ' car(s)';
end;

If the '... has ... car(s)' is not a fixed string, you do not have a well-defined problem. The simplest approach that will yield a well-defined problem and a solution is to add a second TEdit control. Now, let the two comboboxes and the first edit control share the same OnChange event:

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
  Edit2.Text := Format(Edit1.Text, [ComboBox1.Text, ComboBox2.Text]);
end;

Now the user can enter, for example, %s has %s car(s). in the first edit box.

However, if you know that the string entered by the user in the edit box will contain exactly one item from each combobox, and that no other part of the string coincides with a combobox item, then, of course, you can dynamically replace the item in the edit box. Then let the comboboxes share this event:

procedure TForm1.ComboBox1Change(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to ComboBox1.Items.Count - 1 do
    if Pos(ComboBox1.Items[i], Edit1.Text) > 0 then
    begin
      Edit1.Text := StringReplace(Edit1.Text, ComboBox1.Items[i],
        ComboBox1.Text, [rfReplaceAll]);
      break;
    end;
  for i := 0 to ComboBox2.Items.Count - 1 do
    if Pos(ComboBox2.Items[i], Edit1.Text) > 0 then
    begin
      Edit1.Text := StringReplace(Edit1.Text, ComboBox2.Items[i],
        ComboBox2.Text, [rfReplaceAll]);
      break;
    end;
end;

To try this, set the comboboxes to Sue and 2, and write Sue and I have 3 cats. Sue is cute.. Now try to change the comboboxes!

You can make this more robust by only replacing the old combobox text with the new one. To accomplish this, you need to save the previous value in the combobox. At any rate, you cannot, even in theory, make this completely robust. Indeed, what if the string is 'Bill called 911 when he got a heart attack paying his electric bill 5 days ago.' This string might very well end up as 'Sue called 26 when he got a heart attack paying his electric Sue 26 days ago.'

More subtly, if one of the combobox items is 'car' and another is 'train', then 'carnage' might be transformed to 'trainnage'.

Upvotes: 7

Related Questions