Reputation: 3258
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! : )
Upvotes: 1
Views: 282
Reputation: 17138
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;
Upvotes: 10
Reputation: 21950
I'm rusty on Delphi, but I think you may need an "override" on your constructor declaration.
Upvotes: 3