【发布时间】:2012-08-25 04:17:32
【问题描述】:
我正在编写一个 TCustomDBGrid 后代组件,它需要访问受保护的属性 Options(TGridOptions),它是 TCustomDBGrid 对象的父类 (TCustomGrid) 的一部分。问题是在 TCustomDBGrid 类中存在一个具有相同名称的属性重新引入,但具有另一种类型 (TDBGridOptions)。
检查简化此声明
TCustomGrid= = class(TCustomControl)
protected
//I need to access this property
property Options: TGridOptions read FOptions write SetOptions
default [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine,
goRangeSelect];
end;
TCustomDBGrid = class(TCustomGrid)
protected
//a property with the same name is reintroduced in this class
property Options: TDBGridOptions read FOptions write SetOptions
default [dgEditing, dgTitles, dgIndicator, dgColumnResize, dgColLines,
dgRowLines, dgTabs, dgConfirmDelete, dgCancelOnExit, dgTitleClick, dgTitleHotTrack];
end;
TDBGridEx = class(TCustomDBGrid)
protected
//inside of this method I need to access the property TCustomGrid.Options
procedure FastDraw(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);
end;
我想出了如何使用一个破解器类来访问这个属性。
type
TCustomGridClass=class(TCustomGrid);
{ TDBGridEx }
procedure TDBGridEx.FastDraw(ACol, ARow: Integer; ARect: TRect; AState: TGridDrawState);
var
LOptions: TGridOptions;
LRect : TRect;
begin
......
LOptions := TCustomGridClass(Self).Options; //works fine
LRect := ARect;
if not (goFixedVertLine in LOptions) then
Inc(LRect.Right);
if not (goFixedHorzLine in LOptions) then
Inc(LRect.Bottom);
.....
end;
但只是出于好奇我想知道是否存在另一种解决方法或解决此问题的更好方法。
【问题讨论】:
-
这是我见过的针对这种情况的唯一解决方法。如果有另一种解决方案,我会感到惊讶,但对于写得很好的问题 +1。 :-)
-
写
LOptions := inherited TCustomGrid Options;之类的东西会很好:) -
如果需要访问隐藏属性,我会认真考虑重新设计组件。我想没有更好的技巧来解决您的问题。
-
@Serg:通常我会同意你的看法。但在这种情况下,需求不是来自正在设计的组件,而是来自其祖先。 VCL 并不完全适合扩展。许多方法和属性的可见性低于对扩展控件的帮助,许多可用于干净扩展设计的方法没有标记为虚拟。
-
@WarrenP:是的,但并不是每个人都愿意为此投入时间和精力。虽然 GUI 很重要,但如果我只需要一些调整,我宁愿将稀缺资源投入构建业务逻辑,也不愿为了简洁的设计而重新发明控件......