3

想使用 Sender 作为 TObject 作为我的案例的选择标准...声明

procedure TForm.ShowGUI (Sender: TObject);
begin
  case sender of
      ToolButton1: begin
          do_something;         
        end;

      ToolButton2: begin
          /// 
        end;

      ToolButton3: begin
          do_stufff_here; 
        end;

      ToolButton3: begin 
          /// 
        end;

      else ;

  end;
end;

根据 case 语句的要求使发件人成为序数类型的技巧?

4

2 回答 2

10

您可以Sender通过将其转换为整数来轻松地将其转换为序数(例如:NativeUInt(Sender)- 但这对您没有好处,因为该case语句需要“分支”的常量表达式,并且ToolButton1..ToolButton3不是常量,它们是变量。

例如,您可以对按钮的属性进行案例;例如,给每个人ToolButton一个Tag对它有意义的属性。然后你可以做这样的事情:

case (Sender as TToolButton).Tag of
  1: ; // ToolButton1 was pressed
  2: ; // ToolButton2 was pressed        
end;

正如大卫所建议的那样:除非您使用的控件具有与其功能直接相关的属性(非常不可能),否则简单的链式 if 语句可能更易于阅读。我的第一个建议中的Tag属性需要专门配置,这只是引入错误的另一种方式。示例:也许您复制粘贴一个按钮但忘记更改它的标签,您现在有两个具有相同标签的按钮。

首先,您应该从代码中重命名您正在使用的所有组件,给它们正确的名称。然后你可以写这样的东西:

if (Sender = tbAlignTextLeft) then
  begin
     // The tool-button for left text alignment was pressed
  end
else if (Sender = tbAlignTextCenter) then
  begin
    // Center-alignment button was pressed
  end
else
  begin
    // This would be the default action. If it were me, I'd raise an exception here.
  end
于 2013-02-14T08:03:56.090 回答
6

考虑添加一些运行时支持以将枚举与控件相关联。

首先创建一个枚举类型:

type
  TControlID = (cidAlignTextLeft, cidAlignTextRight, ....);

然后将字典添加到您的表单中:

FControlIDs: TDictionary<TControl, TControlID>;

然后在表单的构造函数中创建并填充字典:

FControlIDs := TDictionary<TControl, TControlID>.Create;
FControlIDs.Add(tbAlignTextLeft, cidAlignTextLeft);
FControlIDs.Add(tbAlignTextRight, cidAlignTextRight);
....

这部分代码应该放在单独的本地帮助函数中,而不是内联在表单的构造函数中。

现在你可以写你的case语句:

case FControlIDs[Sender as TControl] of
cidAlignTextLeft:
  ....
cidAlignTextRight:
  ....
于 2013-02-14T08:54:50.777 回答