请问有谁有处理这样情况的方法:
要设置窗体上一类控件的属性, 比如数据感知控件的只读属性,可以这样处理:
for i:=0 to Self.ComponentCount - 1 do
begin
if Components[i] is TDBMemo then
(Components[i] as TDBMemo).ReadOnly := True;
if Components[i] is TDBEdit then
(Components[i] as TDBEdit).ReadOnly := True;
...
...
end;但是这样的话就有个问题,如果使用的控件类多。这样做是很呆板的。那就只能每次再添加语句了
if Components[i] is ?then
(Components[i] as ?).ReadOnly := True;
因为要考虑使用的通用,像TDBMemo、TDBEdit都是继承自TCustomEdit 的ReadOnly属性,是否可以如此:
if Components[i] is TCustomEdit then
(Components[i] as TCustomEdit).ReadOnly := True; // 编译不通过
但此时问题发生,TCustomEdit的ReadOnly是保护属性,没有公开;好像记得以前看过一个针对DBGrid固定列使用方法,但在此处情况不同。有使用基类保护属性的方法么?于是,考虑另一种替代方式,只需要添加常量数组:
const
BASEDBNAMELEN = 2;
BASEDBNAME : array[0..BASEDBNAMELEN-1] of TClass// 类名
=(TDBMemo, TDBEdit);
var
i, j: Integer;
begin
for i:=0 to Self.ComponentCount - 1 do
begin
for j:=0 to BASEDBNAMELEN -1 do
begin
if Components[i] is BASEDBNAME[j] then Break;
end;
if j < BASEDBNAMELEN then
(Components[i] as BASEDBNAME[j]).ReadOnly := True; // 编译不通过
end;
end;
但又返回到编译不通过的路上,使用FieldAddress方法只能找到公开字段,找不到属性。现在又只能回到原来的方法了, 有谁有更好的解决方案么?
要设置窗体上一类控件的属性, 比如数据感知控件的只读属性,可以这样处理:
for i:=0 to Self.ComponentCount - 1 do
begin
if Components[i] is TDBMemo then
(Components[i] as TDBMemo).ReadOnly := True;
if Components[i] is TDBEdit then
(Components[i] as TDBEdit).ReadOnly := True;
...
...
end;但是这样的话就有个问题,如果使用的控件类多。这样做是很呆板的。那就只能每次再添加语句了
if Components[i] is ?then
(Components[i] as ?).ReadOnly := True;
因为要考虑使用的通用,像TDBMemo、TDBEdit都是继承自TCustomEdit 的ReadOnly属性,是否可以如此:
if Components[i] is TCustomEdit then
(Components[i] as TCustomEdit).ReadOnly := True; // 编译不通过
但此时问题发生,TCustomEdit的ReadOnly是保护属性,没有公开;好像记得以前看过一个针对DBGrid固定列使用方法,但在此处情况不同。有使用基类保护属性的方法么?于是,考虑另一种替代方式,只需要添加常量数组:
const
BASEDBNAMELEN = 2;
BASEDBNAME : array[0..BASEDBNAMELEN-1] of TClass// 类名
=(TDBMemo, TDBEdit);
var
i, j: Integer;
begin
for i:=0 to Self.ComponentCount - 1 do
begin
for j:=0 to BASEDBNAMELEN -1 do
begin
if Components[i] is BASEDBNAME[j] then Break;
end;
if j < BASEDBNAMELEN then
(Components[i] as BASEDBNAME[j]).ReadOnly := True; // 编译不通过
end;
end;
但又返回到编译不通过的路上,使用FieldAddress方法只能找到公开字段,找不到属性。现在又只能回到原来的方法了, 有谁有更好的解决方案么?
begin
Result := FDataLink.ReadOnly;
end;procedure TDBEdit.SetReadOnly(Value: Boolean);
begin
FDataLink.ReadOnly := Value;
end;你说的这几个控件的 ReadOnly 属性与其父类 TCustomEdit 的 ReadOnly 好象无关#-_-...
这几个东西的 ReadOnly 实际上都是其第一个成员的 ReadOnly 属性
父类又不一样,老老实实把所有控件加弄进去做个函数~~~好象偷懒是8行的了
如果在基类中增加一个监听方法,用于实现某种特定的接口,比如IReadable,然后在在使用的时候对所有控件广播该消息,是可以实现的。
这种设计思想需要你对Delphi的VCL基层做一些修改。
思想可以参考李维的《深入VCL核心》
var i:integer;
begin
for i:=1 to 10 do
TMemo(self.FindComponent('memo'+IntToStr(i))).ReadOnly:=false;
end;
TAA = class(TA);然后就可以随便访问TA的保护属性和保护方法了, 如下:
TAA(A).Prochttp://www.e-jun.com/bbs