如何在Delphi中执行此操作:
procedure ToggleVisibility(ControlClass : TControlClass);
var
i : integer;
begin
for i := 0 to ComponentCount - 1 do
if Components[i] is ControlClass then
ControlClass(Components[i]).Visible := not Control(Components[i]).Visible;
end;
编译器在这种情况下不允许强制转换。有什么想法吗?
我正在使用Delphi 2007。
答案 0 :(得分:10)
由于组件是TControl
或后代,您必须强制转换为TControl
:
procedure ToggleVisibility(ComponentClass : TControlClass);
var
i : integer;
begin
for i := 0 to ComponentCount - 1 do begin
if Components[i] is ComponentClass then
TControl(Components[i]).Visible := not TControl(Components[i]).Visible;
end;
end;
答案 1 :(得分:2)
(Components[i] as ComponentClass).Visible
答案 2 :(得分:2)
转换ComponentClass(Components [i])没有意义。可见,因为.Visible需要是特定的类,才能正确编译。因此,您需要指定应该转换为的确切类。例如,如果TControl具有.Visible属性,但派生类创建了一种新的.Visible属性,编译器将不知道它应该编译哪两个属性。
所以问题是,你想要反转TControl.Visible,然后你应该写(Components [i]作为TControl).Visible。我猜这就是你想要的。
如果你想要反转任何TControl后代的.Visible,无论它是否与可见的控件相关,无论它是否与TControl相关。可见或不可用,那么你应该去RTTI其他地方描述的解决方案。
答案 3 :(得分:1)
使用RTTI
尝试此选项Uses
TypInfo;
procedure TForm1.ToggleVisibility(ComponentClass: TClass);
var
i : integer;
PropInfo: PPropInfo;
aValue : Variant;
begin
for i := 0 to ComponentCount - 1 do
if Components[i] is ComponentClass then
begin
PropInfo := GetPropInfo(Components[i].ClassInfo, 'Visible');
if Assigned(PropInfo) then
begin
aValue:=GetPropValue(Components[i], 'Visible');
if PropInfo.PropType^.Kind=tkEnumeration then //All enumerated types. This includes Boolean, ByteBool, WordBool, LongBool and Bool
SetOrdProp(Components[i], PropInfo, Longint(not Boolean(aValue)));
end;
end;
end;
执行
ToggleVisibility(TEdit);