【问题标题】:How to identify which control is Sender?如何识别哪个控件是Sender?
【发布时间】:2016-01-02 01:29:09
【问题描述】:

我对所有虚拟树视图 (TVirtualStringTree) 使用通用程序,因此我只需要维护 1 个代码,例如对于 OnClick,我使用所有 VST 控件都设置的 Common_VST_OnClick:

procedure TForm1.Common_VST_OnClick(Sender: TObject);

为了根据 VST 在点击过程中调用它来执行代码,我意识到我使用了许多不同的方法来识别哪个控件是 Sender:

if Sender = VST1 then   

if Sender.Name = VST1.Name then    

if TVirtualStringTree(Sender) = VST1 then

if TVirtualStringTree(Sender).Name = VST1.Name then

if TVirtualStringTree(Sender).Name = 'VST1' then

最后一个可能是最糟糕的,因为名称是硬编码的,所以我试图在所有程序中只使用一种类型的标识。

识别哪个控件是 Sender 的最佳方法是什么?

【问题讨论】:

  • 您的第一个是正确的 - if Sender = VST1 是最正确的方法。但是,如果您正在编写依赖于识别特定组件的所谓通用代码,那么您可能做错了什么。
  • 是的,我明白了,我在第一句话中就给了你信息。您仍然将 generic 函数的使用限制为特定名称的组件:if Sender = VST1 then...else if Sender = VST2 then... 等。如果您有特定于控件的代码,请为每个控件使用单独的事件处理程序。如果代码应该作用于任何 VST 控件,那么您不需要知道它的名称是哪一个。
  • 在您编辑之后,我可以更肯定地说您的代码是错误的。您应该有一个接受 VST 和数组作为参数的过程,并在该 VST 上执行该常见操作(无论它是哪一个),然后每个单独 VST 的 OnClick 处理程序将调用该过程传递自身和合适的数组。您重复的if Sender = 表明您正在编写特定于控件的代码并试图使其通用,这根本不是正确的做事方式。当维护变得困难(或不可能)时,您最终会意识到这一点。
  • @MikeTorrettinni 您的第二次编辑并没有解决您的问题。事实上,这只会使情况变得更糟。如何?从一种方法你现在已经做了三个。我假设您仍在您的GetDataGetLinkedData 方法中使用该if sender = ...。您应该避免使用我所说的 mile long if's or case statements 为什么,因为它们的不同部分迟早会开始在您看来相同。因此,当您认为您正在为一个 VST 进行更改时,您可能正在进行影响另一个 VST 的更改,或者您将创建一个新的错误而不是修复错误。 ...
  • .. 我去过那里,做过,但我不喜欢它。现在正确的方法是使用面向对象的方法并派生 VST 组件的自定义类,以便您可以向它们添加自定义方法。然后,这些方法可以从您的第二次编辑中替换您当前的 GetDataGetLinkedData。而且由于这些方法特定于每个 VST,并且在自定义 VST 范围内执行,因此您不再需要所有这些 if's 来检查哪个控件是发送者,而只需调用 Sender.GetDataSender.GetLinkedData

标签: delphi delphi-xe7 sender virtualtreeview


【解决方案1】:

您应该更喜欢使用对象身份的测试。也就是说,您问题中的第一个测试:

if Sender = VST1 then

SenderVST1 等对象引用是对象的地址。如果两个这样的地址相等,则引用指向同一个对象。反之亦然。

基于控件名称的测试可以工作但很脆弱。多个控件可以具有相同的名称。可以更改控件名称,但不能更新程序中名称的所有用途。

关于类型转换选项

if TVirtualStringTree(Sender) = VST1 then

类型转换对对象身份没有影响,因此是不必要的。永远不要将操作数类型转换为对象身份测试,因为这样做是虚假的。

【讨论】:

  • 太好了,大约 200 LOC 发生了变化,并且按预期工作!代码更简洁。
  • @DavidHeffernan 很抱歉恢复了这个,但最好在这里问而不是发一个新帖子。如果我这样做 if Sender = Button1 那么我可以做 ButtonTag = (Sender as TButton).tag 并使用该标签然后从列表中删除一个对象吗?所以 ObjectList.delete(ButtonTag-1) 我会有 -1 因为我的标签从 1 开始。
  • @miketorrettinni 你知道吗?
  • @你不一定会数数
  • @davidheffernan 我是的,我认为 TObjectList 从索引 0 开始?
猜你喜欢
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-05
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
相关资源
最近更新 更多