0

私は何時間もこのクレイジーな問題と戦ってきましたが、どこにも行き着きませんでした. TCollection を使用する 2 つの完全に異なるプロジェクトでこの問題が発生します。新しいコレクション アイテムが追加されたら、そのアイテムの値を初期化する必要があります。ただし、デフォルトはまったくありません。アイテムのコンストラクターとコレクションの add 関数の 2 つの完全に異なる場所にそれらを設定していますが、どちらも機能していません。アイテムがあれば値を設定できますが、デフォルト値を設定する必要があります。私は過去にコレクションを行ったことがありますが、この問題は一度もありませんでした。ここに何かが欠けているに違いありません...

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.
4

1 に答える 1

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.
于 2011-11-14T05:22:30.770 に答える