许多时候你需要把界面中的所有数据感知控件的Readonly都设为true或false,你会怎么做呢?
最早的时候我这样:枚举每个类型,如果有更多,代码将会很多
for i := 0 to ComponentCount - 1 do begin
if Components[i] is TDBMemo then begin
TDBMemo(Components[i]).ReadOnly := true;
continue;
end;
if Components[i] is TDBRadioGroup then begin
TDBRadioGroup(Components[i]).ReadOnly := true;
continue;
end;
if Components[i] is TDBEdit then begin
TDBEdit(Components[i]).ReadOnly := true;
continue;
end;
......................
之后我这样,因为数据感知控件都有DataSource和DataField属性,于是使用rtti的信息来设置
for i := 0 to ComponentCount - 1 do begin
if IsPublishedProp(Components[i], 'DataSource') and
IsPublishedProp(Components[i], 'DataField') then
SetVariantProp(Components[i],'ReadOnly',true);
我想这已经是delphi下最短的代码了,别忘了加入TypInfo单元
由此想到如果所有的数据感知控件都实现了IDataControl(假想中的名称)接口,我们由TObject.IsImplementorOf来确定是否是一个数据感知控件,这样就不用用上面的DataSource和DataField判断,就非常规范,而且又可以减少一行代码.这样你在操作一组有共性的类时,不用去枚举各个类防止编译错误(如第一种方法),也不用根据经验来找到他们的共性来界定它们(如第2种方法). 我甚至偏执的认为每个类的public方法和published属性都应该在一个接口的定义中,毕竟你不能保证它是唯一的,有可能会有其他的类似类. 而在赋值的时候就只需要把它as 成interface, 代码可能就是下面这个样子
for i := 0 to ComponentCount - 1 do begin
if Components[i].IsImplementorOf(IDataControl) then
(Components[i] as IDataControl).ReadOnly := true;