Question

This is a continuation of the project I was working on here: Circular reference issue with Classes which use each other

The advice received there fixed the ciruclar reference problem (again, thanks for the help). Now I'm wrestling w/something else: TcmDataPanel.FObservingDataPanels always ends up = nil, apparently because it never gets created. (Initially I was getting an Access Violation, but on further testing it turned out that FObserver was always nil).

Here is the relevant code (it is a TFrame unit, with TcmTPDataPanel being the TFrame descednent):

unit cmTPDataPanelFrame;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, cmTPBasePanelFrame, cmTPPanels, nxdb, nxllComponent;

type
  TcmTPDataConnector = class;

  TcmTPDataPanel = class(TcmTPBasePanel)
    Database: TnxDatabase;
    Session: TnxSession;
  private
    FDataConnector: TcmTPDataConnector;
    MyNxDataBase: TnxDatabase;
    MyNxSession: TnxSession;
    MyRefNxDataBase: TnxDatabase;
  protected
    procedure Disconnect; virtual; abstract;
    procedure Refresh; virtual;
    procedure Requery; virtual; abstract;
  public
    procedure Connect;
  published
    property DataConnector: TcmTPDataConnector read FDataConnector write
        FDataConnector;
  end;

  TcmTPCustomDataConnector = class(TComponent)
  private
    FDatabase: TnxDatabase;
    FObservingDataPanels: TList;
    FTableForCategories: TnxTable;
    FTableForItemCategoryLinks: TnxTable;
    FTableForItems: TnxTable;
    procedure SetTableForItemCategoryLinks(const Value: TnxTable);
  protected
    procedure IterateObservers;
  public
    constructor Create(AOwner: TComponent);
    destructor Destroy; override;
    procedure Register(Instance: TcmTPDataPanel);
    procedure ReportObservers;
    procedure Unregister(Instance: TcmTPDataPanel);
  published
    property Database: TnxDatabase read FDatabase write FDatabase;
    property TableForCategories: TnxTable read FTableForCategories write
        FTableForCategories;
    property TableForItemCategoryLinks: TnxTable read
        FTableForItemCategoryLinks write SetTableForItemCategoryLinks;
    property TableForItems: TnxTable read FTableForItems write FTableForItems;
  end;

  TcmTPDataConnector = class(TcmTPCustomDataConnector)
  end;


var
  cmTPDataPanel: TcmTPDataPanel;

implementation

=== and ===

{
*************************** TcmTPCustomDataConnector ***************************
}
constructor TcmTPCustomDataConnector.Create(AOwner: TComponent);
begin
  ShowMessage('TcmTPCustomDataConnector.Create entered.');
//  inherited Create(AOwner); // TODO : check duplicate
  FObservingDataPanels := TList.Create();
end;

destructor TcmTPCustomDataConnector.Destroy;
begin
  FreeAndNil(FObservingDataPanels);
//inherited Destroy; // TODO : check duplicate
end;

The ShowMessage line that I expect to run on cmTPDataConnector.Create never shows up, which makes me think it's not inheriting the Create method from TcmTPCUstomDataConnector. Shouldn't it be?

It "feels" like there is something obvious I'm missing, but I'm not seeing it. :-\

Two questions:

1) Why is FObservingDataPanels not getting created?
2) The "// inherited Create(AOwner); // TODO : check duplicate" and "//inherited Destroy; // TODO : check duplicate" lines were put in by ModelMaker at some point. Should they be uncommented?

P.S. Obviously, I'm still learning about component creation and inheritance. Any other input and advice is welcome.

P.P.S. Lots of questions from me today. Feel free to let me know if I need to drop it down a notch.... (just having a bonus lots-of-questions day here).

Thanks in advance for any and all help! : )

Was it helpful?

Solution

You need to override your constructor, and then call inherited as the /first/ thing in that constructor.

  public
    constructor Create(AOwner: TComponent); override;



constructor TcmTPCustomDataConnector.Create(AOwner: TComponent);
begin
  inherited Create(AOwner); // TODO : check duplicate
  ShowMessage('TcmTPCustomDataConnector.Create entered.');
  FObservingDataPanels := TList.Create();
end;

OTHER TIPS

I'm rusty on Delphi, but I think you may need an "override" on your constructor declaration.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top