Title: Create your own TreeNodes!
Question: I want to store more information in a TreeNode. Is there any other way than using the Data property?
Answer:
Using the Data property is quite a mess, since you can only use pointers and have to do a lot of typecasting. Here's a better solution:
1) Derive your own TTreeView class
2) Derive your own TTreeNode class
3) Implement a register procedure
4) Install your new component and start using it
//--------------------------------------------------------------------------
// CustomTree contains the Custom Tree componetn and the Node definition
//
unit CustomTree;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls;
type
TMyTreeView = class(TCustomTreeView)
protected
function CreateNode: TTreeNode; override;
function CanCollapse(Node: TTreeNode): Boolean; override;
published
property Align;
property Anchors;
property AutoExpand;
property BiDiMode;
property BorderStyle;
property BorderWidth;
property ChangeDelay;
property Color;
property Ctl3D;
property Constraints;
property DragKind;
property DragCursor;
property DragMode;
property Enabled;
property Font;
property HideSelection;
property HotTrack;
property Images;
property Indent;
property ParentBiDiMode;
property ParentColor default False;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ReadOnly;
property RightClickSelect;
property RowSelect;
property ShowButtons;
property ShowHint;
property ShowLines;
property ShowRoot;
property SortType;
property StateImages;
property TabOrder;
property TabStop default True;
property ToolTips;
property Visible;
property OnAdvancedCustomDraw;
property OnAdvancedCustomDrawItem;
property OnChange;
property OnChanging;
property OnClick;
property OnCollapsed;
property OnCollapsing;
property OnCompare;
property OnContextPopup;
property OnCustomDraw;
property OnCustomDrawItem;
property OnDblClick;
property OnDeletion;
property OnDragDrop;
property OnDragOver;
property OnEdited;
property OnEditing;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnExpanding;
property OnExpanded;
property OnGetImageIndex;
property OnGetSelectedIndex;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnStartDock;
property OnStartDrag;
{ Items must be published after OnGetImageIndex and OnGetSelectedIndex }
property Items;
end;
TMyTreeNode = class(TTreeNode)
private
FStartdate: TDateTime;
FHappy: boolean;
FSurName: string;
protected
procedure SetSurName(const Value: string);
public
constructor Create(AOwner: TTreeNodes);
destructor Destroy; override;
property StartDate: TDateTime read FStartDate write FStartDate;
property Happy: boolean read FHappy write FHappy;
property SurName: string read FSurName write SetSurName;
end;
procedure Register;
implementation
{ TMyTreeView }
function TMyTreeView.CreateNode: TTreeNode;
begin
Result := TMyTreeNode.Create(Items);
end;
function TMyTreeView.CanCollapse(Node: TTreeNode): Boolean;
begin
result := false;
result := inherited CanCollapse(Node);
end;
{ TMyTreeNode }
constructor TMyTreeNode.Create(AOwner: TTreeNodes);
begin
inherited Create(AOwner);
FStartDate := now;
FHappy := true;
FSurName := '';
end;
destructor TMyTreeNode.Destroy;
begin
// free any objects you created
inherited;
end;
procedure TMyTreeNode.SetSurName(const Value: string);
begin
if Value FSurName then begin
FSurName := Value;
self.Text := FSurName;
end;
end;
procedure Register;
begin
RegisterComponents('delphi3000.com', [TMyTreeView]);
end;
end.
//--------------------------------------------------------------------------
// CustTree contains the package code for installing the component onto your
// component palette
//
package CustTree;
{$R *.RES}
{$ALIGN ON}
{$ASSERTIONS ON}
{$BOOLEVAL OFF}
{$DEBUGINFO ON}
{$EXTENDEDSYNTAX ON}
{$IMPORTEDDATA ON}
{$IOCHECKS ON}
{$LOCALSYMBOLS ON}
{$LONGSTRINGS ON}
{$OPENSTRINGS ON}
{$OPTIMIZATION ON}
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
{$REFERENCEINFO ON}
{$SAFEDIVIDE OFF}
{$STACKFRAMES OFF}
{$TYPEDADDRESS OFF}
{$VARSTRINGCHECKS ON}
{$WRITEABLECONST ON}
{$MINENUMSIZE 1}
{$IMAGEBASE $400000}
{$IMPLICITBUILD OFF}
requires
vcl50;
contains
CustomTree in 'CustomTree.pas';
end.
//--------------------------------------------------------------------------
// CustomTreeTestMain is a demo program
//
unit CustomTreeTestMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, CustomTree;
type
TForm1 = class(TForm)
MyTreeView1: TMyTreeView;
Button1: TButton;
Edit1: TEdit;
Label1: TLabel;
CheckBox1: TCheckBox;
DateTimePicker1: TDateTimePicker;
Label2: TLabel;
Label3: TLabel;
Edit2: TEdit;
Label4: TLabel;
procedure Button1Click(Sender: TObject);
procedure MyTreeView1Change(Sender: TObject; Node: TTreeNode);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
with TMyTreeNode(MyTreeView1.Items.AddChild(MyTreeView1.Selected, Edit1.Text)) do
begin
Happy := CheckBox1.Checked;
SurName := Edit2.Text;
StartDate := DateTimePicker1.DateTime;
end;
end;
procedure TForm1.MyTreeView1Change(Sender: TObject; Node: TTreeNode);
begin
with TMyTreeNode(Node) do
begin
Edit1.Text := Caption;
Edit2.Text := SurName;
DateTimePicker1.DateTime := StartDate;
CheckBox1.Checked := Happy;
end;
end;
end.