[英]Delphi pass object as parameter on click event
I have this code: 我有以下代码:
for LSidebarButton in SidebarButtons do
begin
LSidebarOverlay := TPanel(LSidebarButton.Button.Controls[3]);
LSidebarOverlay.OnClick := SetSidebarButtonActive(nil, LSidebarButton);
end;
And then I have a procedure 然后我有一个程序
procedure SetSidebarButtonActive(sender: TObject; btn: TSidebarButton);
begin
btn.SetActive;
//more code
end;
And I'm getting this error: 我收到此错误:
E2010 Incompatible types: 'TNotifyEvent' and 'procedure, untyped pointer or untyped parameter'
The error is because you are trying to call SetSidebarButtonActive()
and then assign its result (which it has none) to the OnClick
event. 该错误是因为您试图调用 SetSidebarButtonActive()
,然后将其结果(没有结果SetSidebarButtonActive()
分配给OnClick
事件。 That will not work. 那不管用。
The OnClick
event is defined as a TNotifyEvent
: OnClick
事件定义为TNotifyEvent
:
TNotifyEvent = procedure(Sender: TObject) of object;
That means that 那意味着
the procedure needs to be a member of a class 该程序必须是课程的成员
you have to assign the address of the procedure to OnClick
, not call the procedure 您必须将过程的地址分配给OnClick
,而不是调用过程
the procedure must take only 1 input parameter, which is the TObject
that fires the event (in this case, the TPanel
that is being clicked on). 该过程必须仅接受1个输入参数,这是引发事件的TObject
(在这种情况下,是单击的TPanel
)。
So, for what you are attempting, you would need to do something more like this instead: 因此,对于您尝试的操作,您将需要执行以下操作:
procedure TMyForm.DoSomething;
var
...
LSidebarButton: TSidebarButton;
LSidebarOverlay: TPanel;
...
begin
...
for LSidebarButton in SidebarButtons do
begin
LSidebarOverlay := TPanel(LSidebarButton.Button.Controls[3]);
LSidebarOverlay.OnClick := SetSidebarButtonActive;
end;
...
end;
procedure TMyForm.SetSidebarButtonActive(Sender: TObject);
var
Pnl: TPanel;
Btn: TSidebarButton;
begin
Pnl := TPanel(Sender);
Btn := (Pnl.Parent as TSidebarButton);
// or maybe (Pnl.Parent.Parent as TSidebarButton)?
// or maybe (Pnl.Owner as TSidebarButton)?
// or maybe (Pnl.Parent.Owner as TSidebarButton)?
// Hard to know with your example. Use whatever you
// need to get back to the TSidebarButton from its
// inner child TPanel...
Btn.SetActive;
...
end;
Alternatively, you can store the TSidebarButton
reference in the TPanel.Tag
property (assuming you are not using it for something else): 另外,您可以将TSidebarButton
引用存储在TPanel.Tag
属性中(假设您没有将其用于其他用途):
procedure TMyForm.DoSomething;
var
...
LSidebarButton: TSidebarButton;
LSidebarOverlay: TPanel;
...
begin
...
for LSidebarButton in SidebarButtons do
begin
LSidebarOverlay := TPanel(LSidebarButton.Button.Controls[3]);
LSidebarOverlay.Tag := NativeInt(LSidebarButton);
LSidebarOverlay.OnClick := SetSidebarButtonActive;
end;
...
end;
procedure TMyForm.SetSidebarButtonActive(Sender: TObject);
var
Btn: TSidebarButton;
begin
Btn := TSidebarButton(TPanel(Sender).Tag);
Btn.SetActive;
...
end;
Alternatively, you can define a helper class to provide you access to the TSidebarButton
without looking at the TPanel
at all: 另外,您可以定义一个帮助程序类以提供对TSidebarButton
访问,而无需查看TPanel
:
type
TOverlayClickHelper = class(TComponent)
public
Button: TSidebarButton;
procedure OnClick(Sender: TObject);
end;
...
procedure SetSidebarButtonActive(Btn: TSidebarButton);
begin
Btn.SetActive;
//more code
end;
procedure TOverlayClickHelper.OnClick(Sender: TObject);
begin
SetSidebarButtonActive(Button);
end;
procedure TMyForm.DoSomething;
var
...
LSidebarButton: TSidebarButton;
LSidebarOverlay: TPanel;
Helper: TOverlayClickHelper;
...
begin
...
for LSidebarButton in SidebarButtons do
begin
LSidebarOverlay := TPanel(LSidebarButton.Button.Controls[3]);
Helper := TOverlayClickHelper(LSidebarOverlay.FindComponent('MyHelper'));
if Helper = nil then
begin
Helper := TOverlayClickHelper.Create(LSidebarOverlay);
Helper.Name := 'MyHelper';
end;
Helper.Button := LSidebarButton;
LSidebarOverlay.OnClick := Helper.OnClick;
end;
...
end;
Alternatively, if you are creating the TPanel
objects yourself inside of TSidebarButton
, you could simply derive a new class from TPanel
to add a TSidebarButton
reference to it: 另外,如果您正在创建的TPanel
对象自己的内部TSidebarButton
,你可以简单地从派生新类TPanel
到添加TSidebarButton
参考吧:
type
TSidebarButtonPanel = class(TPanel)
public
Button: TSidebarButton;
end;
...
procedure TSidebarButton.CreateOverlay;
var
LOverlay: TSidebarButtonPanel;
begin
LOverlay := TSidebarButtonPanel.Create(Self);
LOverlay.Parent := Self.Button;
LOverlay.Button := Self;
...
end;
...
procedure TMyForm.DoSomething;
var
...
LSidebarButton: TSidebarButton;
LSidebarOverlay: TPanel;
...
begin
...
for LSidebarButton in SidebarButtons do
begin
LSidebarOverlay := TPanel(LSidebarButton.Button.Controls[3]);
LSidebarOverlay.OnClick := SetSidebarButtonActive;
end;
...
end;
procedure TMyForm.SetSidebarButtonActive(Sender: TObject);
var
Btn: TSidebarButton;
begin
Btn := TSidebarButtonPanel(Sender).Button;
Btn.SetActive;
...
end;
There are all kinds of options available to you. 您可以使用各种选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.