Software Software
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?
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?
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.
If you want to use control names, you can use methods like "FindControl" and "FindComponent" once you have constructed the appropriate 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;
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...
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;
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:
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 TRIALMembers 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.
double click on the first button to make an event handler
delphi makes this:
Open in new window
you can identify which button it is like this:
Open in new window
on your other buttons, open the object inspector events tab, and in the dropdown for onclick, select the OnClickButton1