Delphi 2009:传递组件名称 onclick 事件然后设置属性
我有一个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
最终,您会问如何告诉
ViewComments
函数它正在使用哪个按钮的属性。您了解
Sender
参数在OnClick
事件中的作用吗?它告诉事件处理程序正在处理哪个对象的事件。它正是您希望为ViewComments
函数发挥的作用。这就是梅森在回答中想要表达的意思。不要传递所有属性值,而是传递对象本身:
然后从所有按钮的事件处理程序中调用它:
没有字符串,没有
case
语句,没有查找。这应该可以回答你的问题,但你可以做得更好。还记得我之前所说的关于
Sender
参数吗?当有人单击第一个按钮时,OnClick
处理程序的Sender
参数将是该按钮,因此我们可以像这样重写第一个事件处理程序:并且您可以重写第二个 事件处理程序像这样的事件处理程序:
嗯。他们是一样的。拥有两个相同的功能是一种浪费,因此删除一个并重命名另一个,这样它听起来就不是特定于按钮的:
然后设置两个按钮的
OnClick
属性来引用到那个事件处理程序。您不能仅通过双击对象检查器中的属性来完成此操作。您需要自己键入名称,从下拉列表中选择名称,或者在运行时分配事件属性:我还想鼓励您为控件使用更有意义的名称。那个
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 theOnClick
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 theViewComments
function.That's what Mason was getting at in his answer. Rather than pass all the property values, pass the object itself:
Then call it from all your buttons' event handlers:
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, theSender
parameter of thatOnClick
handler will be the button, so we can rewrite the first event handler like this:And you can rewrite the second event handler like this:
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:
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: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 itEditInProgressLabel
, for instance.既然您已经传递了额外的变量,为什么不直接传递 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.
对代码进行小的更改应该可以解决问题:
编辑注释后:
您还可以记住按钮本身,而不仅仅是它的名称。
A small change to your code should do the trick:
and after editing the comment:
You can also memorize the button itself instead of just it's name.