【发布时间】: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 您的第二次编辑并没有解决您的问题。事实上,这只会使情况变得更糟。如何?从一种方法你现在已经做了三个。我假设您仍在您的
GetData和GetLinkedData方法中使用该if sender = ...。您应该避免使用我所说的mile long if's or case statements为什么,因为它们的不同部分迟早会开始在您看来相同。因此,当您认为您正在为一个 VST 进行更改时,您可能正在进行影响另一个 VST 的更改,或者您将创建一个新的错误而不是修复错误。 ... -
.. 我去过那里,做过,但我不喜欢它。现在正确的方法是使用面向对象的方法并派生 VST 组件的自定义类,以便您可以向它们添加自定义方法。然后,这些方法可以从您的第二次编辑中替换您当前的
GetData和GetLinkedData。而且由于这些方法特定于每个 VST,并且在自定义 VST 范围内执行,因此您不再需要所有这些if's来检查哪个控件是发送者,而只需调用Sender.GetData或Sender.GetLinkedData。
标签: delphi delphi-xe7 sender virtualtreeview