我在Delphi 10 Seattle中看到了TActivityIndicator的介绍,我觉得很酷,我可以在某个地方使用它。我想用它来表明我的表单的一些动态创建的部分仍然在填充表单之前加载数据。所以我想在开始在FormShow
中加载数据之前我会这样做,其中self就是形式。
indicator := TActivityIndicator.Create(self);
indicator.IndicatorSize := TActivityIndicatorSize.aisLarge;
可悲的是,当我尝试动态创建它们然后设置TActivityIndicator.IndicatorSize
时,我得到一个异常... EInvalidOperation with message 'Control '<name>' has no parent window'
通过VCL单步执行Vcl.Controls TWinControl.CreateWnd
专门
if (WndParent = 0) and (Style and WS_CHILD <> 0) then
if (Owner <> nil) and (csReading in Owner.ComponentState) and
(Owner is TWinControl) then
WndParent := TWinControl(Owner).Handle
else
raise EInvalidOperation.CreateFmt(SParentRequired, [Name]);
我已经检查Owner
表单当然是TWinControl,但(csReading in Owner.ComponentState)
返回false。单步执行FormCreate上的Owner.ComponentState = []和FormShow上的[csFreeNotification]。
我发现如果您尝试更改在设计时创建的TActivityIndicator的IndicatorSize
,那么它可以完美地运行。那么我在这里缺少什么,或者是否无法在运行时创建TActivityIndicators
?
答案 0 :(得分:4)
错误信息非常清楚。您需要指定活动指示器将自行绘制的Parent
。 Owner
是负责在所有者被销毁时释放控制权的组件; Parent
是控件将被绘制(对象)以供显示的控件。
解决方案是在代码中分配该父代:
Indicator := TActivityIndicator.Create(Self);
Indicator.Parent := Self; // <-- here
// Set any other properties here
同样的问题在所有视觉控件上都很常见(例如TEdit
,TLabel
,TMemo
等等,所有这些都需要Parent
分配为了有一个自己画画的地方。在某些情况下,需要Parent
才能使子控件中的各种属性在依赖于具有HWND
窗口的子窗口时正常运行,这需要Parent
窗口,等等。
如果我明白你的意图,我认为你会感到失望。 TActivityIndicator
非常静态;它没有线程,这意味着如果您的表单繁忙并且没有处理定时器消息(它在内部使用),它将停止更新。