当前位置 : 主页 > 编程语言 > delphi >

在Delphi 6中为动态创建的VCL组件实例显式调用Loaded方法的替代方法?

来源:互联网 收集:自由互联 发布时间:2021-06-23
我有几个自定义VCL组件,它们在重写TComponent Loaded()方法时执行重要任务.这在动态创建实例时会产生麻烦,因为在运行时Delphi全局加载器不会调用Loaded()方法,就像在设计时放置在窗体/框架
我有几个自定义VCL组件,它们在重写TComponent Loaded()方法时执行重要任务.这在动态创建实例时会产生麻烦,因为在运行时Delphi全局加载器不会调用Loaded()方法,就像在设计时放置在窗体/框架上的组件一样.我还必须将Loaded覆盖放在类声明的公共部分中,因此无论创建组件实例的代码都可以调用它.最后,我必须记住为动态创建的实例调用Loaded(),否则细微的bug会蔓延到应用程序中,这个问题已经让我好几次了.

有更好的解决方案或方法吗?

如果你需要在你的代码中调用Loaded你做错了.如果你依赖第三方控制,那么我会修复那个人的控制权.请参阅下文.

让我举一个假设的例子:假设我有5个已发布的属性,一旦它们全部被加载,可以生成复杂的曲线甚至更好,生成分形,这需要很长时间.

在设计时我想在加载后立即预览此曲线,但我不希望在DFM流式传输期间重新计算曲线5次,因为每个参数P1到P5(类型为Double)都有一个SetP1方法,它调用一个受保护的方法名为Changed,并重建我的曲线.相反,如果csDesigning或csLoading处于组件状态,我会返回SetP1方法,然后我从Loaded调用一次Changed.显然,在所有情况下,我都不能单独依赖属性设置器方法来调用所有更改.所以我需要Loaded告诉我做第一代一些昂贵的工作,我想要完成一次,而不是N次,其中N是已经加载的具有方法设置过程的DFM属性的数量调用名为Changed的方法或类似的方法.

在您的情况下,在运行时,您根本不应该依赖于Loaded被调用.相反,您应该将属性集方法调用Changed.如果你需要某种方法一次更改多个属性,然后只做一次昂贵的事情,那么实现TMyComponent.BeginUpdate / TMyComponent.EndUpdate类型的方法调用,并避免额外的工作.

我认为没有任何有用的地方,从Loaded做一些事情是有意义的,除了上面的情况,这应该是特定于设计时和基于DFM的类使用.我希望正确设计的TComponent或TControl只需通过在代码中创建并通过设置其属性来正确初始化自身.

因此,对于我假设的TMyFractal组件,我会在代码中创建它时执行此操作,而无需使用DFM加载或调用Loaded:

cs := TMyFractal.Create(Self);
  cs.Parent := Self; {Parent to a form}
  cs.Align := alClient;
  cs.BeginUpdate;
  cs.P1 := 1.03;  // does NOT trigger Regenerate
  cs.P2 := 2.3;
  cs.P3 := 2.4;
  cs.P4 := 2.5;
  cs.EndUpdate; // triggers expensive Regenerate method .
  cs.Show; 

  // later someone wants to tweak only one parameter and I don't want to make them
  // call regenerate:
  cs.P5 := 3.0; // Each param change regenerates the whole curve when not loading or in a beginupdate block.

在我的TMyFractal.Change方法中,我会调用昂贵的RegenerateCurve方法一次,每次在运行时修改任何系数P1-P4,在初始设置之后,并且恰好在组件从DFM流入时,其中Loaded仅用于处理我很难指望在我的控件中执行beginupdate / endupdate的事实,就像我在上面的代码中所做的那样.

网友评论