Link to home
Start Free TrialLog in
Avatar of Software Software
Software SoftwareFlag for Austria

asked on

Delphi: Implement only one delete button

I have 100 buttons and 100 edits. They are named button1, button2, ..., button100 and edit1, edit2, ..., edit100.
When I click on Button1 then edit1 should be deleted. When I click on Button100 then edit100 should be deleted etc.
How can I do this, without implementing 100 time the same code. I want to implement it only once.
What is an intelligent solution?

User generated image
Avatar of Geert G
Geert G
Flag of Belgium image

each button has a distinct name (if you don't make it empty)

double click on the first button to make an event handler
delphi makes this:

procedure TForm1.OnClickButton1(Sender: TObject);
begin
  
end;

Open in new window


you can identify which button it is like this:
procedure TForm1.OcClickButton1(Sender: TObject);
var s: string;
begin
  if Sender is TButton then 
  begin
    s := TButton(Sender).Name;
    // instead of showmessage, use you code
    ShowMessage('Button pressed : ' + s);
    // if you name all your buttons like Button1, Button2, ... Button100
    // get the number like: 
    // n: integer;
    //  n := StrToInt(Copy(TButton(Sender).Name, 7, 5));
    // above converts char 7 from the name, for 5 long, to an integer

  end;  
end;

Open in new window


on your other buttons, open the object inspector events tab, and in the dropdown for onclick, select the OnClickButton1
I would at this stage be questioning the validity of having 100 edits and 100 buttons in any user interface. There is nothing "wrong" with this, but surely there is a better way of organising what you want to achieve? The other expert's answer is a way to go if you really want to do this. Other ways are doing things like assigning tags to controls and changing actions based on the control's tag. I prefer the latter because it does not couple an action to a potentially meaningless control name.

Generally speaking, leaving control names as their default is great for UI design speed but bad for reading code and maintaining the code. In your situation there is little wrong with it given the simplicity of the UI. If you have a more complex UI, reading code that refers to controls such as eUserName and ePassword makes more sense than reading references to edit1 and edit2. With that in mind, in most situations you would name controls meaningfully.

To allow meaningful naming and simpler code, you could set the tag on an edit and the corresponding button to be the same and then in the button click event locate the edit by the button's tag and clear it. Something like the below code in the button click event will work. Usually I would avoid the use of "exit" in loops and I would write the below using a while loop, but I have added it for simplicity and also because many other Delphi programmers seem quite happy to use the exit statement.

My use of "begin" and "end" may not necessarily be conventional (as with the layout), but I tend to use them to make code blocks look relatively consistent and to convey programmer intent.  Technically speaking, you could remove some of them and the code would still be syntactically valid. Seeing where I have used them should make it clear to a reader what my intention was.

procedure TForm1.OnButtonClick(Sender: TObject);
var
  i: Integer;
begin
  if Sender is TButton then begin
    for i := 0 to ComponentCount - 1 do begin
      if (Components[i] is TEdit) and (TEdit(Components[i]).Tag = TButton(Sender).Tag) then begin
        TEdit(Components[i]).Clear;
        exit;
      end;
    end;
  end;
end;

Open in new window


If you want to use control names, you can use methods like "FindControl" and "FindComponent" once you have constructed the appropriate control name.
Agree with Martyn... bad ui design. Better describe what you really want - we can help you. For non-experienced users is is hard to start...
Sometimes it is better to reverse logic and solutions comes up...
As the others have stated, this isn't somehting I would personally write, but if you must, you must;

The Tag property is an easy way to do this.  If you set each buttons tag property to the same number as the edits tag property, (Button1.Tag=1, Edit1.Tag1, etc), the code below will do the trick;
NOTE:  This code is safe so that clicking a button that has no associated edit (like the 2nd click) will not cause an exception since it won't be found.

procedure TForm1.ButtonClick(Sender: TObject);
var
    myButton    : TButton;
    myEdit      : TEdit;

    ndx         : Integer;
begin
    // Always check just to be sure
    if NOT(Sender is TButton) then
        Exit;

    //assign to a local varialbe for easier usage
    myButton := TButton(Sender);

    // Locate the appropriate tedit.
    for ndx := 0 to ControlCount-1 do
        if (Controls[ndx]) is TEdit then begin
            myEdit := TEdit(Controls[ndx]);
            if myEdit.Tag = myButton.Tag then begin
                myEdit.Free;
                break;
            end;
        end;

end;
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.