Delphi 2009:传递组件名onclick事件,然后设置属性

Delphi 2009:传递组件名onclick事件,然后设置属性,delphi,components,onclick,custom-component,Delphi,Components,Onclick,Custom Component,我有一个TSpeedButton类型的自定义组件,它定义了两个额外的属性: CommentHeading: string; CommentText: string; 我在设计时设置了标题 当按下“速度”按钮时,会显示一个备忘录,其下方有一个按钮用于保存其内容。处理此问题的过程: procedure CustomSpeedButton1Click(Sender: TObject); begin Receiver := CustomSpeedButton1.Name; // possibly

我有一个TSpeedButton类型的自定义组件,它定义了两个额外的属性:

CommentHeading: string;
CommentText: string;
我在设计时设置了标题

当按下“速度”按钮时,会显示一个备忘录,其下方有一个按钮用于保存其内容。处理此问题的过程:

procedure CustomSpeedButton1Click(Sender: TObject);
begin
   Receiver := CustomSpeedButton1.Name; // possibly used to save the memo text back to this speedbuttons property after comments are submitted
   ViewComments(CustomSpeedButton1.CommentTitle,CustomSpeedButton1.CommentText);
end;
以及ViewComments过程本身:

procedure ViewComments(comment_caption:string; comment_text:string);
begin
  label15.Hide; // label showing editing in progress, hidden until user begins typing
  Button1.Enabled     := false; // the button for saving the memo text, hidden until user begins typing
  CommentsBox.Visible := true; // pop up the comment box at the bottom of the form
  CommentsBox.Caption := 'Comments: ' + comment_caption;
  CommentsMemo.Text   := comment_text; // if there are existing comments assign them to memo
end;
备忘录的内容需要分配给自定义SpeedButton的CommentText属性

我最初的想法是,我可以在按下自定义SpeedButton时将组件名称传递给变量,然后在按下备忘录上的save按钮时检索该名称,并使用它将备忘录文本分配给speedbuttons CommentText属性。但后来我意识到,要做到这一点,我必须使用某种形式的case..语句,检查每个可能的speedbutton名称,然后将memo值分配给它的属性,这看起来太无聊了


有没有更简单的方法将备忘录文本分配给打开备忘录的speedbutton?

既然您已经在传递额外的变量,为什么不直接传递speedbutton本身呢?那么您就不需要查找引用了。

既然您已经在传递额外的变量,为什么不直接传递SpeedButton本身呢?这样您就不需要查找引用了。

对代码做一点小改动就可以了:

procedure TForm1.CustomSpeedButton1Click(Sender: TObject);
var
  btn: TCustomSpeedButton;
begin
   btn := Sender as TCustomSpeedButton;
   Receiver := btn.Name; 
   ViewComments(btn.CommentTitle, btn.CommentText);
end;
编辑评论后:

procedure TForm1.StoreComments(comment: string);
var
  btn: TCustomSpeedButton;
begin
  btn := FindComponent(Receiver) as TCustomSpeedButton;
  btn.CommentText := comment;
end;

您还可以记住按钮本身,而不仅仅是它的名称。

对您的代码进行一点小小的更改就可以做到这一点:

procedure TForm1.CustomSpeedButton1Click(Sender: TObject);
var
  btn: TCustomSpeedButton;
begin
   btn := Sender as TCustomSpeedButton;
   Receiver := btn.Name; 
   ViewComments(btn.CommentTitle, btn.CommentText);
end;
编辑评论后:

procedure TForm1.StoreComments(comment: string);
var
  btn: TCustomSpeedButton;
begin
  btn := FindComponent(Receiver) as TCustomSpeedButton;
  btn.CommentText := comment;
end;

您还可以记住按钮本身,而不仅仅是它的名称。

最后,您要问的是如何告诉
viewcoments
函数它使用的是哪个按钮的属性

您是否了解
Sender
参数在
OnClick
事件中的作用?它告诉事件处理程序正在处理哪个对象的事件。它正是您希望为
viewcoments
功能带来的角色

这就是梅森在回答中的意思。传递对象本身,而不是传递所有属性值:

然后从所有按钮的事件处理程序调用它:

procedure TForm1.CustomSpeedButton1Click(Sender: TObject);
begin
  ViewComments(CustomSpeedButton1);
end;

procedure TForm1.CustomSpeedButton2Click(Sender: TObject);
begin
  ViewComments(CustomSpeedButton2);
end;
没有字符串,没有大小写语句,没有查找

这应该能回答你的问题,但你可以做得更好。还记得我之前说过的关于
Sender
参数的话吗?当有人单击第一个按钮时,该
OnClick
处理程序的
Sender
参数将是该按钮,因此我们可以像这样重写第一个事件处理程序:

procedure TForm1.CustomSpeedButton1Click(Sender: TObject);
begin
  ViewComments(Sender as TCustomSpeedButton);
end;
procedure TForm1.CustomSpeedButton2Click(Sender: TObject);
begin
  ViewComments(Sender as TCustomSpeedButton);
end;
您可以像这样重写第二个事件处理程序:

procedure TForm1.CustomSpeedButton1Click(Sender: TObject);
begin
  ViewComments(Sender as TCustomSpeedButton);
end;
procedure TForm1.CustomSpeedButton2Click(Sender: TObject);
begin
  ViewComments(Sender as TCustomSpeedButton);
end;
嗯,他们是一样的。拥有两个相同的函数是浪费时间的,因此请去掉其中一个并重命名另一个,这样它就不会听起来像按钮特定的:

procedure TForm1.CommentButtonClick(Sender: TObject);
begin
  ViewComments(Sender as TCustomSpeedButton);
end;
然后设置两个按钮的
OnClick
属性以引用该事件处理程序。仅通过双击“对象检查器”中的属性是无法做到这一点的。您需要自己键入名称、从下拉列表中选择名称或在运行时分配事件属性:

CustomSpeedButton1.OnClick := CommentButtonClick;
CustomSpeedButton2.OnClick := CommentButtonClick;

我还想鼓励您为控件使用更有意义的名称。那
标签15
特别令人震惊。您怎么能记得第十五个标签是表示正在进行编辑的标签?例如,将其称为
EditInProgressLabel

最终,您要问的是如何告诉
ViewComments
函数它使用的是哪个按钮的属性

您是否了解
Sender
参数在
OnClick
事件中的作用?它告诉事件处理程序正在处理哪个对象的事件。它正是您希望为
viewcoments
功能带来的角色

这就是梅森在回答中的意思。传递对象本身,而不是传递所有属性值:

然后从所有按钮的事件处理程序调用它:

procedure TForm1.CustomSpeedButton1Click(Sender: TObject);
begin
  ViewComments(CustomSpeedButton1);
end;

procedure TForm1.CustomSpeedButton2Click(Sender: TObject);
begin
  ViewComments(CustomSpeedButton2);
end;
没有字符串,没有大小写语句,没有查找

这应该能回答你的问题,但你可以做得更好。还记得我之前说过的关于
Sender
参数的话吗?当有人单击第一个按钮时,该
OnClick
处理程序的
Sender
参数将是该按钮,因此我们可以像这样重写第一个事件处理程序:

procedure TForm1.CustomSpeedButton1Click(Sender: TObject);
begin
  ViewComments(Sender as TCustomSpeedButton);
end;
procedure TForm1.CustomSpeedButton2Click(Sender: TObject);
begin
  ViewComments(Sender as TCustomSpeedButton);
end;
您可以像这样重写第二个事件处理程序:

procedure TForm1.CustomSpeedButton1Click(Sender: TObject);
begin
  ViewComments(Sender as TCustomSpeedButton);
end;
procedure TForm1.CustomSpeedButton2Click(Sender: TObject);
begin
  ViewComments(Sender as TCustomSpeedButton);
end;
嗯,他们是一样的。拥有两个相同的函数是浪费时间的,因此请去掉其中一个并重命名另一个,这样它就不会听起来像按钮特定的:

procedure TForm1.CommentButtonClick(Sender: TObject);
begin
  ViewComments(Sender as TCustomSpeedButton);
end;
然后设置两个按钮的
OnClick
属性以引用该事件处理程序。仅通过双击“对象检查器”中的属性是无法做到这一点的。您需要自己键入名称、从下拉列表中选择名称或在运行时分配事件属性:

CustomSpeedButton1.OnClick := CommentButtonClick;
CustomSpeedButton2.OnClick := CommentButtonClick;

我还想鼓励您为控件使用更有意义的名称。那
标签15
特别令人震惊。您怎么能记得第十五个标签是表示正在进行编辑的标签?例如,将其称为
EditInProgressLabel

这仍然引出了一个问题,即如何告诉“保存”按钮哪个SpeedButton打开了备忘录,而不必使用case..of语句?我试图避免任何形式的大量查找,因为表单上会有数百个这样的注释按钮。我不太明白问题出在哪里。将一个SpeedButton引用与每个注释相关联,当您打开一条注释时,为其提供一个对打开该注释的按钮的引用。然后,当您保存时,您拥有的任何引用都是要将其分配回的按钮。不需要查找。这仍然引出了一个问题,即如何告诉“保存”按钮哪个SpeedButton打开了备忘录,而无需使用案例。