TCollectionItem未初始化默认属性值

时间:2011-11-14 03:51:01

标签: delphi delphi-7 custom-component tcollectionitem

我一直在与这个疯狂的问题作斗争几个小时而且无处可去。我在使用TCollection的两个完全不同的项目中遇到此问题。添加新的集合项时,我需要初始化该项的值。但是,它们根本不是默认的。我甚至将它们设置在两个完全不同的位置,在项目的构造函数中,以及在集合的add函数中 - 它们都不起作用。我可以在项目存在后设置值,但我需要设置默认值。我以前做过收藏,从来没有遇到过这个问题,我必须在这里遗漏一些东西......

unit JDGrids;

interface

uses
  Classes, Windows, SysUtils, Grids, StrUtils;

type
  TJDGridCol = class;
  TJDGridCols = class;  

  TJDGridCols = class(TCollection)
  private
    fOnEvent: TNotifyEvent;
  private
    fOwner: TComponent;
    procedure DoEvent;
    property OnEvent: TNotifyEvent read fOnEvent write fOnEvent;
  protected
    function GetItem(Index: Integer): TJDGridCol;
    procedure SetItem(Index: Integer; Value: TJDGridCol);
    function GetOwner: TPersistent; override;
  public
    constructor Create(AOwner: TComponent);
    destructor Destroy; override;
    function Add: TJDGridCol;
    procedure Assign(Source: TPersistent); override;
    procedure Clear;
    procedure Delete(Index: Integer);
    property Items[Index: Integer]: TJDGridCol read GetItem write SetItem; default;
  end;

  TJDGridCol = class(TCollectionItem)
  private
    fOwner: TComponent;
    fWidth: Integer;
    fTitle: String;
    fCols: TJDGridCols;
    fOnEvent: TNotifyEvent;
    fVisible: Bool;
    procedure SetTitle(const Value: String);
    procedure SetWidth(const Value: Integer);
    procedure DoEvent;
    property OnEvent: TNotifyEvent read fOnEvent write fOnEvent;
    procedure SetVisible(const Value: Bool);
  protected
    function GetDisplayName: String; override;
  public
    constructor Create(AOwner: TJDGridCols);
    destructor Destroy; override;
  published
    property Title: String read fTitle write SetTitle;
    property Width: Integer read fWidth write SetWidth;
    property Visible: Bool read fVisible write SetVisible;
  end;

implementation

{ TJDGridCols }

constructor TJDGridCols.Create(AOwner: TComponent);
begin
  inherited Create(TJDGridCol);
  fOwner:= AOwner;
end;

destructor TJDGridCols.Destroy;
begin

  inherited Destroy;
end;

function TJDGridCols.Add: TJDGridCol;
begin
  Result:= TJDGridCol(inherited Add);
  Result.fCols:= Self;
  Result.fTitle:= 'Column '+IntToStr(Result.ID);
  Result.fWidth:= 30;
  Result.fVisible:= True;
  DoEvent;
end;

procedure TJDGridCols.Assign(Source: TPersistent);
begin
  inherited Assign(Source);
  DoEvent;
end;

procedure TJDGridCols.Clear;
begin
  inherited Clear;
  DoEvent;
end;

procedure TJDGridCols.Delete(Index: Integer);
begin
  inherited Delete(Index);
  DoEvent;
end;

function TJDGridCols.GetItem(Index: Integer): TJDGridCol;
begin
  Result:= TJDGridCol(inherited Items[Index]);
end;

function TJDGridCols.GetOwner: TPersistent;
begin
  Result:= fOwner;
end;

procedure TJDGridCols.SetItem(Index: Integer; Value: TJDGridCol);
begin
  inherited Items[Index]:= Value;
  DoEvent;
end;

procedure TJDGridCols.DoEvent;
begin
  if assigned(fOnEvent) then fOnEvent(Self);
end;

{ TJDGridCol }

constructor TJDGridCol.Create(AOwner: TJDGridCols);
begin
  inherited Create(AOwner);
  fOwner:= AOwner.fOwner;
  fCols:= AOwner;
  fTitle:= 'Column '+IntToStr(ID);
  fWidth:= 30;
  fVisible:= True;
end;

destructor TJDGridCol.Destroy;
begin

  inherited Destroy;
end;

procedure TJDGridCol.DoEvent;
begin
  if assigned(fOnEvent) then fOnEvent(Self);
end;

function TJDGridCol.GetDisplayName: String;
begin
  Result:= fTitle;
end;

procedure TJDGridCol.SetTitle(const Value: String);
begin
  fTitle:= Value;
  DoEvent;
end;

procedure TJDGridCol.SetVisible(const Value: Bool);
begin
  fVisible := Value;  
  DoEvent;
end;

procedure TJDGridCol.SetWidth(const Value: Integer);
begin
  fWidth := Value;
  DoEvent;
end;

end.

1 个答案:

答案 0 :(得分:2)

您没有覆盖TCollection的构造函数,因此TCollection.Add()无法调用您的构造函数。这就是您需要Add()设置默认值的原因。

即使这样,您在构造期间设置了默认属性值,但是您没有在属性声明中指定相同的默认值。您需要这样做才能使DFM流正常工作。

您还应该使用TOwnedCollection而不是直接使用TCollection。让TOwnedCollection为您管理所有者。

试试这个:

unit JDGrids;

interface

uses
  Classes, Windows, SysUtils, Grids, StrUtils;

type
  TJDGridCol = class;

  TJDGridCols = class(TOwnedCollection)
  private
    fOnEvent: TNotifyEvent;
  private
    procedure DoEvent;
    property OnEvent: TNotifyEvent read fOnEvent write fOnEvent;
  protected
    function GetItem(Index: Integer): TJDGridCol;
    procedure SetItem(Index: Integer; Value: TJDGridCol);
  public
    constructor Create(AOwner: TComponent); reintroduce;
    destructor Destroy; override;
    function Add: TJDGridCol; reintroduce;
    procedure Assign(Source: TPersistent); override;
    procedure Clear; reintroduce;
    procedure Delete(Index: Integer); reintroduce;
    property Items[Index: Integer]: TJDGridCol read GetItem write SetItem; default;
  end;

  TJDGridCol = class(TCollectionItem)
  private
    fWidth: Integer;
    fTitle: String;
    fOnEvent: TNotifyEvent;
    fVisible: Bool;
    procedure SetTitle(const Value: String);
    procedure SetWidth(const Value: Integer);
    procedure DoEvent;
    procedure SetVisible(const Value: Bool);
    property OnEvent: TNotifyEvent read fOnEvent write fOnEvent;
  protected
    function GetDisplayName: String; override;
    function GetCols: TJDGridCols;
    function GetOwner: TComponent;
  public
    constructor Create(AOwner: TCollection); override;
    destructor Destroy; override;
  published
    property Title: String read fTitle write SetTitle;
    property Width: Integer read fWidth write SetWidth default 30;
    property Visible: Bool read fVisible write SetVisible default True;
  end;

implementation

{ TJDGridCols }

constructor TJDGridCols.Create(AOwner: TComponent);
begin
  inherited Create(AOwner, TJDGridCol);
end;

destructor TJDGridCols.Destroy;
begin
  inherited Destroy;
end;

function TJDGridCols.Add: TJDGridCol;
begin
  Result := TJDGridCol(inherited Add);
  DoEvent;
end;

procedure TJDGridCols.Assign(Source: TPersistent);
begin
  inherited Assign(Source);
  DoEvent;
end;

procedure TJDGridCols.Clear;
begin
  inherited Clear;
  DoEvent;
end;

procedure TJDGridCols.Delete(Index: Integer);
begin
  inherited Delete(Index);
  DoEvent;
end;

function TJDGridCols.GetItem(Index: Integer): TJDGridCol;
begin
  Result:= TJDGridCol(inherited Items[Index]);
end;

procedure TJDGridCols.SetItem(Index: Integer; Value: TJDGridCol);
begin
  inherited SetItems(Index, Value);
  DoEvent;
end;

procedure TJDGridCols.DoEvent;
begin
  if Assigned(fOnEvent) then fOnEvent(Self);
end;

{ TJDGridCol }

constructor TJDGridCol.Create(AOwner: TCollection);
begin
  inherited Create(AOwner);
  fTitle := 'Column ' + IntToStr(ID);
  fWidth := 30;
  fVisible := True;
end;

destructor TJDGridCol.Destroy;
begin
  inherited Destroy;
end;

procedure TJDGridCol.DoEvent;
begin
  if Assigned(fOnEvent) then fOnEvent(Self);
end;

function TJDGridCol.GetDisplayName: String;
begin
  Result := fTitle;
end;

function TJDGridCol.GetCols: TJDGridCols;
begin
  Result := Collection as TJDGridCols;
end;

function TJDGridCol.GetOwner: TComponent;
begin
  Result := GetCols.GetOwner as TComponent;
end;

procedure TJDGridCol.SetTitle(const Value: String);
begin
  if fTitle <> Value then
  begin
    fTitle := Value;
    DoEvent;
  end;
end;

procedure TJDGridCol.SetVisible(const Value: Bool);
begin
  if fVisible <> Value then
  begin
    fVisible := Value;  
    DoEvent;
  end;
end;

procedure TJDGridCol.SetWidth(const Value: Integer);
begin
  if fWidth <> Value then
  begin
    fWidth := Value;
    DoEvent;
  end;
end;

end.