除了Delphi中的默认“Sender:TObject”之外,是否可以向OnClick事件添加其他参数?

时间:2011-01-07 21:01:28

标签: delphi onclick parameter-passing

我正在使用Delphi进行A2计算项目,并且在向事件过程添加其他参数时遇到了问题。

我正在创建一些标签(TLabel对象)并将它们存储在我的主窗体“form1”下的数组中。

这就是我目前的情况:

**传递标签数组的声明和相应的ClickEvent过程以及传递的标准(Sender:TObject)参数。

 public
     InventoryLabel : array [0..23] of TLabel;
     procedure InventoryLabelClick(Sender: TObject);

**这是与上面声明的ClickEvent匹配的过程。 (该程序的内容非常混乱,但与问题相关,是我目前使用的目标。)

Procedure TForm1.InventoryLabelClick(Sender: TObject);
begin
if sender = InventoryLabel[0] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[0]].cardpic);
if sender = InventoryLabel[1] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[1]].cardpic);
if sender = InventoryLabel[2] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[2]].cardpic);
if sender = InventoryLabel[3] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[3]].cardpic);
if sender = InventoryLabel[4] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[4]].cardpic);
if sender = InventoryLabel[5] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[5]].cardpic);
if sender = InventoryLabel[6] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[6]].cardpic);
if sender = InventoryLabel[7] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[7]].cardpic);
if sender = InventoryLabel[8] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[8]].cardpic);
if sender = InventoryLabel[9] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[9]].cardpic);
if sender = InventoryLabel[10] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[10]].cardpic);
if sender = InventoryLabel[11] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[11]].cardpic);
if sender = InventoryLabel[12] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[12]].cardpic);
if sender = InventoryLabel[13] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[13]].cardpic);
if sender = InventoryLabel[14] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[14]].cardpic);
if sender = InventoryLabel[15] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[15]].cardpic);
if sender = InventoryLabel[16] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[16]].cardpic);
if sender = InventoryLabel[17] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[17]].cardpic);
if sender = InventoryLabel[18] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[18]].cardpic);
if sender = InventoryLabel[19] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[19]].cardpic);
if sender = InventoryLabel[20] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[20]].cardpic);
if sender = InventoryLabel[21] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[21]].cardpic);
if sender = InventoryLabel[22] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[22]].cardpic);
if sender = InventoryLabel[23] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[23]].cardpic); 
end;

**这是创建标签并为其提供属性的代码。

for I := 0 to 23 do
  begin
    InventoryLabel[i] := TLabel.Create(nil);
      with InventoryLabel[i] do
        begin
          Parent := Inventory;
          left := 8;
          OnClick := InventoryLabelClick;
          visible := false;
        end;
end;

这一切都非常好并且有效(ish)但是我想在我调用“InventoryLabelClick”过程时传递一个参数,在这种情况下变量“I”将是按下哪个标签的参考。这将允许我删除所有“if sender = inventorylabel [x]”(x是上面的任何数字),而只是替换为第二位“imgInvItem.Picture.LoadFromFile(redcarddeck [redcardpositionsofinventory [I]]。 cardpic);”但是使用参数“I”而不是数字“x”(与上面相同)。

我尝试了以下编辑,看它是否有用。

**在声明中更改

Public
   procedure InventoryLabelClick(Sender: TObject; I: Integer);

**为实施中的程序更改

Procedure TForm1. InventoryLabelClick(Sender: TObject; I: Integer);

**然后当它分配给对象的事件

for I := 0 to 23 do
  begin
    InventoryLabel[i] := TLabel.Create(nil);
      with InventoryLabel[i] do
        begin
          Parent := Inventory;
          left := 8;
          OnClick := InventoryLabelClick;
          visible := false;
        end;
end;

** sender参数是默认值,因此在第一种情况下无需声明它。但是,当有多个参数时,它会要求两者。

运行时,会返回错误消息“

  

E2010不兼容的类型:'TNotifyEvent'和'过程,无类型指针或无类型参数'

“我认为这意味着我已经宣布参数错误。

有人能帮我解决这个问题吗?如果事实证明不可能像我上面尝试的那样传递一个额外的参数,那么有人会建议一种使代码更整洁的方法吗?

提前致谢。

3 个答案:

答案 0 :(得分:7)

将“i”值保存在TLabel的Tag属性中。

for I := 0 to 23 do begin
  InventoryLabel[i] := TLabel.Create(nil);
  with InventoryLabel[i] do begin
    Parent := Inventory;
    Tag := i;
    left := 8;
    OnClick := InventoryLabelClick;
    visible := false;
  end;
end;

然后,在OnClick事件中,键入cast Sender to TLabel并读取Tag值以获取点击的标签:

Procedure TForm1.InventoryLabelClick(Sender: TObject);
  begin
    imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[TLabel(Sender).Tag]].cardpic);
  end;

答案 1 :(得分:3)

你为什么不这样做?

Procedure TForm1.InventoryLabelClick(Sender: TObject);
var i : integer;
begin
  for i := 0 to 23 do
    if sender = InventoryLabel[i] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[i]].cardpic);
end;

当然,最好的方法是使InventoryLabel不是TLabel,而是一个封装TLabel和LoadPicture方法的自定义类,所以你可以这样做:

Procedure TForm1.InventoryLabelClick(Sender: TObject);
begin
  Sender.LoadPicture;
end;

但这将会有更多的工作。

答案 2 :(得分:2)

您无法更改TNotifyEvent的签名。您必须使用自己的OnClick事件创建自定义标签控件,该事件接受其他参数。这可能比学校项目的保证工作更多,一般情况下我不建议编写自定义控件,除非你没有其他选择。

然而,有一种更简单的方法。

Procedure TForm1.InventoryLabelClick(Sender: TObject);
var
  I: Integer;
begin
  for I := Low(InventoryLabel) to High(InventoryLabel)do
    if Sender = InventoryLabel[I] then
      imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[I]].cardpic);
end;