Delphi 发件人作为案例的对象。。。与德尔福的合作

Delphi 发件人作为案例的对象。。。与德尔福的合作,delphi,Delphi,希望使用发件人作为对象作为我的案例的选择标准。。。声明 procedure TForm.ShowGUI (Sender: TObject); begin case sender of ToolButton1: begin do_something; end; ToolButton2: begin /// end; ToolButton3: begin

希望使用发件人作为对象作为我的案例的选择标准。。。声明

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语句所要求的序号类型的技巧?

您可以通过将
发送方
转换为整数(例如:
NativeUInt(sender)
)轻松地将其转换为序号,但这对您没有好处,因为
case
语句要求“分支”使用常量表达式,和
ToolButton1
ToolButton3
不是常量,而是变量

例如,您可以对按钮的属性执行一个案例;例如,为每个
ToolButton
指定一个对其有意义的
Tag
属性。然后您可以执行以下操作:

case (Sender as TToolButton).Tag of
  1: ; // ToolButton1 was pressed
  2: ; // ToolButton2 was pressed        
end;
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
正如David所建议的:除非您使用的控件具有与其功能直接相关的属性(非常不可能),然后一个简单的链接if语句可能更容易阅读。我的第一个建议中的
标记
属性需要专门配置,这只是引入错误的另一种方式。例如:可能您复制粘贴了一个按钮,但忘了更改它的标记,现在有两个按钮具有相同的标记

首先,您应该从代码中重命名您正在使用的所有组件,并为它们指定适当的名称。然后您可以编写如下内容:

case (Sender as TToolButton).Tag of
  1: ; // ToolButton1 was pressed
  2: ; // ToolButton2 was pressed        
end;
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

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

首先创建枚举类型:

type
  TControlID = (cidAlignTextLeft, cidAlignTextRight, ....);
然后在表单中添加字典:

FControlIDs: TDictionary<TControl, TControlID>;

一个技巧是创建显示不同GUI类型的操作,并将每个操作分配到适当的按钮。此时Delphi将开始更灵活地处理
case
语句。他们可以在后台自动将case语句转换为一系列
if
语句,允许我们使用非常量express离子和字符串。这将节省我们的体力劳动,因为我们无论如何都在这么做。@Cosmin:Delphi中的模式匹配在一年前的EMBA论坛上讨论过,Nick Hodges,如果我记得清楚的话,甚至把它作为Delphi II语言的一种可能性。+1如果你这样做,我建议你在代码中设置标记,而不是在对象检查器中,并使用constants而不是数字。这可能会使将来的维护更容易。虽然您可以这样做,但if语句会更干净。@DavidHeffernan显然,在这种情况下,
case
会更干净。@Smasher只有在您假装没有编写神奇常量并用
标签< /代码>属性。如果你考虑整个图片,那么<代码>案例选项损失很大。@ SasHER是的,它是很容易阅读的。这不是我的观点。显然我不是很好地表达自己。我的问题是,每个控件必须有一个地方设置“代码>标签< /代码>。case语句中的定量。现在,如果在.dfm文件中这样做,您希望如何维护它?您最好将
TControlID
填充到
标记中,然后为case语句将
Tag
硬转换为
TControlID
。除了字典查找,大致相同。@CosminPrund我有一个很强的缺点
Tag
。使用它会让我感觉脏兮兮的。就像我在VB6中编码一样。如果您忘记为其中一个控件指定
Tag
,那么它默认为
cidAlignTextLeft
!将
cidUnassigned
作为第一个枚举元素来防止这种情况。@CosminPrund肯定可以这样做。我喜欢类型安全。我不喜欢ike
Tag
。我也不喜欢
Sender:TObject
,但这方面没有什么好做的。至少
as
cast强制执行运行时类型安全。