我有此代码:
for LSidebarButton in SidebarButtons do
begin
LSidebarOverlay := TPanel(LSidebarButton.Button.Controls[3]);
LSidebarOverlay.OnClick := SetSidebarButtonActive(nil, LSidebarButton);
end;
然后我有一个程序
procedure SetSidebarButtonActive(sender: TObject; btn: TSidebarButton);
begin
btn.SetActive;
//more code
end;
我收到此错误:
E2010 Incompatible types: 'TNotifyEvent' and 'procedure, untyped pointer or untyped parameter'
答案 0 :(得分:3)
该错误是因为您尝试调用 SetSidebarButtonActive()
,然后将其结果(没有结果)分配给OnClick
事件。那是行不通的。
OnClick
事件被定义为TNotifyEvent
:
TNotifyEvent = procedure(Sender: TObject) of object;
那是
该过程必须是一个类的成员
您必须将过程的地址分配给OnClick
,而不是 call 该过程
过程必须仅接受1个输入参数,即触发事件的TObject
(在这种情况下,单击的TPanel
)。
因此,对于您要尝试的操作,您将需要执行以下操作:
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;
或者,您可以将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;
或者,您可以定义一个帮助程序类,以提供对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;
或者,如果您要自己在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;
您可以使用各种选择。