【问题标题】:How to access a property which is hidden for another property in a child class?如何访问为子类中的另一个属性隐藏的属性?
【发布时间】: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 很重要,但如果我只需要一些调整,我宁愿将稀缺资源投入构建业务逻辑,也不愿为了简洁的设计而重新发明控件......

标签: delphi oop


【解决方案1】:

这是使用class helpers 的另一种解决方法。它不如你的 hack 好,但很有效。

type
  TCustomGridHelper = class helper for TCustomGrid
    function GetGridOptions: TGridOptions;
  end;

function TCustomGridHelper.GetGridOptions: TGridOptions;
begin
  Result := Self.Options;
end;

procedure TDBGridEx.FastDraw(ACol, ARow: Integer; ARect: TRect;
  AState: TGridDrawState);
var
 LOptions: TGridOptions;
 LRect : TRect;
begin
  ...
  LOptions := Self.GetGridOptions; //works fine
  ...
end;

【讨论】:

    猜你喜欢
    • 2020-02-18
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    • 1970-01-01
    • 2021-07-01
    • 1970-01-01
    • 2020-09-17
    相关资源
    最近更新 更多