有更好的解决方案或方法吗?
如果你需要在你的代码中调用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的事实,就像我在上面的代码中所做的那样.