我有一个带有大量控件的表单,我想迭代某个面板上的所有控件并启用/禁用它们.
我试过这个:
var component: TComponent; begin for component in myPanel do (component as TControl).Enabled := Value; end;
但那没有做任何事.原来所有组件都在表单的组件集合中,而不是它们的父对象.那么有谁知道是否有任何方法可以获得控件内的所有控件?(除了像这样的丑陋的解决方法,这是我最终必须做的):
var component: TComponent; begin for component in myPanel do if (component is TControl) and (TControl(component).parent = myPanel) then TControl(component).Enabled := Value; end;
有人请告诉我有更好的方法......
您正在寻找TWinControl.Controls
阵列和附属物ControlCount
.那些是控制的直接孩子.要获得孙子等,请使用标准的递归技术.
你真的不想要的Components
阵列(这是什么for
- in
在循环迭代),因为它没有任何关系,一般来说,与亲子关系.组件可以拥有没有子关系的东西,控件可以拥有他们不拥有的子代.
另请注意,禁用控件也会隐式禁用其所有子项.你不能与残疾人控制的孩子互动; 操作系统不会向它们发送输入消息.但是,要使它们看起来处于禁用状态,您需要单独禁用它们.也就是说,要使按钮具有灰色文本,即使该按钮不响应鼠标单击,也不足以禁用其父项.您需要禁用按钮本身以使其"禁用"自行绘制.
如果禁用面板,则对其进行控制也会被禁用.
使用匿名方法的递归解决方案:
type TControlProc = reference to procedure (const AControl: TControl); procedure TForm6.ModifyControl(const AControl: TControl; const ARef: TControlProc); var i : Integer; begin if AControl=nil then Exit; if AControl is TWinControl then begin for i := 0 to TWinControl(AControl).ControlCount-1 do ModifyControl(TWinControl(AControl).Controls[i], ARef); end; ARef(AControl); end; procedure TForm6.Button1Click(Sender: TObject); begin ModifyControl(Panel1, procedure (const AControl: TControl) begin AControl.Enabled := not Panel1.Enabled; end ); end;