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

发布于 2024-08-02 13:31:24 字数 1356 浏览 10 评论 0原文

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

CommentHeading: string;
CommentText: string;

我在设计时设置 CommentHeading。

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

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 时,我可以将组件名称传递给一个变量,然后在按下备忘录上的保存按钮时检索该名称,并使用它将备忘录文本分配给 speedbuttons CommentText 属性。但后来我意识到,要做到这一点,我必须使用某种 case..of 语句来检查每个可能的快速按钮名称,然后将备忘录值分配给其属性,这看起来非常乏味。

是否有更简单的方法将备忘录文本分配给开始打开备忘录的快速按钮?

I have a custom component of type TSpeedButton that has two extra properties defined:

CommentHeading: string;
CommentText: string;

I set CommentHeading at design time.

When the speed button is pressed a memo is shown with a button beneath it for saving its contents. The procedure that handles this:

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;

And the ViewComments procedure itself:

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;

The contents of the memo need to be assigned to the CommentText property of the custom SpeedButton.

What I was initially thinking was that I could pass the component name to a variable when the custom SpeedButton gets pressed and then retrieve that name when the save button on the memo is pressed and use it to assign the memo text to the speedbuttons CommentText property. But then I realized that to do this I'd have to use some kind of case..of statement that checked for each possible speedbutton name and then assign the memo value to its properties and this just seems ridiculously tedious.

Is there an easier way to assign the memo text to the speedbutton that opened the memo to begin with?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

听,心雨的声音 2024-08-09 13:31:24

最终,您会问如何告诉 ViewComments 函数它正在使用哪个按钮的属性。

您了解 Sender 参数在 OnClick 事件中的作用吗?它告诉事件处理程序正在处理哪个对象的事件。它正是您希望为 ViewComments 函数发挥的作用。

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

procedure ViewComments(CommentButton: TCustomSpeedButton);

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

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

procedure TForm1.CustomSpeedButton2Click(Sender: TObject);
begin
  ViewComments(CustomSpeedButton2);
end;

没有字符串,没有 case 语句,没有查找。

这应该可以回答你的问题,但你可以做得更好。还记得我之前所说的关于 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.CommentButtonClick(Sender: TObject);
begin
  ViewComments(Sender as TCustomSpeedButton);
end;

然后设置两个按钮的 OnClick 属性来引用到那个事件处理程序。您不能仅通过双击对象检查器中的属性来完成此操作。您需要自己键入名称,从下拉列表中选择名称,或者在运行时分配事件属性:

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

我还想鼓励您为控件使用更有意义的名称。那个Label15尤其令人震惊。您如何记住第十五标签是指示编辑正在进行的标签?例如,将其称为 EditInProgressLabel

Ultimately, you're asking how to tell the ViewComments function which button's properties it's working with.

Do you understand what the Sender parameter is doing in the OnClick event? It's telling the event handler which object's event is being handled. It's serving precisely the role that you're looking to bring to the ViewComments function.

That's what Mason was getting at in his answer. Rather than pass all the property values, pass the object itself:

procedure ViewComments(CommentButton: TCustomSpeedButton);

Then call it from all your buttons' event handlers:

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

procedure TForm1.CustomSpeedButton2Click(Sender: TObject);
begin
  ViewComments(CustomSpeedButton2);
end;

No strings, no case statements, no lookups.

That should answer your question, but you can do it even better. Remember what I said before about the Sender parameter? When someone clicks the first button, the Sender parameter of that OnClick handler will be the button, so we can rewrite the first event handler like this:

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

And you can rewrite the second event handler like this:

procedure TForm1.CustomSpeedButton2Click(Sender: TObject);
begin
  ViewComments(Sender as TCustomSpeedButton);
end;

Hmm. They're the same. Having two identical functions is wasteful, so get rid of one and rename the other so it doesn't sound button-specific:

procedure TForm1.CommentButtonClick(Sender: TObject);
begin
  ViewComments(Sender as TCustomSpeedButton);
end;

Then set the OnClick properties of both buttons to refer to that one event handler. You can't do that just by double-clicking the property in the Object Inspector. You'll need to either type the name yourself, choose it from the drop-down list, or assign the event property at run time:

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

I'd also like to encourage you to use more meaningful names for your controls. That Label15 is particularly egregious. How can you remember that the fifteenth label is the one that indicates that editing is in progress? Call it EditInProgressLabel, for instance.

亽野灬性zι浪 2024-08-09 13:31:24

既然您已经传递了额外的变量,为什么不直接传递 SpeedButton 本身呢?那么你就不需要查找参考文献了。

Since you're already passing extra variables around, why not just pass the SpeedButton itself? Then you won't need to look up the reference.

椵侞 2024-08-09 13:31:24

对代码进行小的更改应该可以解决问题:

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;

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

A small change to your code should do the trick:

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

and after editing the comment:

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

You can also memorize the button itself instead of just it's name.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文