That may work, but now you have used up the object holder for each Node's
object. That means that your implementation cannot be descended from
correctly if that place holder is required in the descendant class. The
argument for using helper classes is fine but your new class shouldn't have
less functionality than the descendant class (in this case the NodeObject).
Consider this example:



A Treeview must display a heirarchy  of animals structured according to
their species. As each folder in the treeview is opened (eg "dog") a panel
on the right displays generic information about dogs, plus an icon for each
folder below it (eg "retriever", "poodle"). If the "Retriever" folder is
opened then the panel displays some information about retrievers plus a
list view of summary information about each retriever below it. If a
"Golden Retriever" node is selected from below the retriever folder then
the panel on the right displays detailed information about the golden
retriever, plus an imbeded movie. The kind of infomation displayed is
completely different for other species of animals.



This is just a made up example but it will do. Using an inheritance
structure each node can be added as a (eg.) TRetrieverNode or a TDogNode.
The TDogNode knows how to display the information on the right, and knows
what to pass to and from a persistence mechanism. All the calling code has
to do is call a new "Draw" method, passing in the canvas to draw it's
information to (in this case the panel on the right). The calling code
doesn't care what the node/folder is that is selected because it knows how
to draw itself.

Now if someone wanted to re-use these new TTreeNode descendants and
associate a quick menu (via right mouse) with each kind of node, they can
do it. The quick menu can be stored in the NodeObject for each node because
it hasn't been used.

That won't work as cleanly if you use the helper object approach. Each node
doesn't really know what kind of information it is, it relies on the stored
object to do all the work - but what if the stored object is missing?!?
Could happen - but not if the information is built in to the node itself.
Worse, because the ObjectNode is already used up with the new information
for each node, it is no longer available for use to hold the quick menu.

An even more fundamental problem with the helper object approach in this
case is code reuse. The code for adding the object and calling the relevant
methods and filling the relevant data has to be repeated (or adapted) each
time you want a new treeview. You haven't actually created a new component
that you can reuse later. All you have done is used the TTreeView component
an (I assume in you main code) manged the nodes and objects.



Hope I haven't missunderstood you.



Phil.

[Mark Wrote]

The reason I asked was because I wondered whether you were using some
attribute of the custom node to sort on (vs the text associated with the
node).

The way we achieve node types is to associate a NodeObject with each tree
node (using AddObject/AddChildObject inside our own node management stuff)
- which gives the node a type and holds other information we require. Each
NodeObject also holds a reference to its "OwnerNode" so they can find each
other.

It follows the "Helper Objects" rather than "Class Hierarchies" philosophy,
which imho Delphi is based on - and brought to Java. This seems to simplify
this sort of thing. We then descend from the NodeObject if we want to do
fancy stuff (which incidentally allows the objects to do their own stuff
independently too), or just store information in it if it's a simple tree.
It also allows us to associate images, menu items, as well as behaviours
etc, with each Node Type, stored in the object and doesn't stop the default
tree behaviour, unless we don't surface it.

Max

[phillip Said]

I'm creating an enhanced custom treeview component that allows you to store
descendants from TTreeNode in it. This allows you to set the default node
type, if you wish, to some descendant of TTreeNode and then to either add
nodes normally or specify a node class. For example,

MyNewTreeView.DefaultNodeType := TFancyNode;
MyNewTreeView.Add(AParentNode);

TFancyNode is a descendant from TTreeNode and the DefaultNodeType property
is a metaclass property (ie. class of TTreeNode).
Alternatively, you could call
MyNewTreeView.Add(AParentNode,TFancyNode);

The whole point being that each node knows what it is and can behave
differently if it needs to, rather that the main application code having to
store information in the TTreeNode.Data property and managing the behaviour
itself.

I have it all working fine, but I'm just a bit worried about the sorting
routine for the reason I have already given.



---------------------------------------------------------------------------
    New Zealand Delphi Users group - Delphi List - [EMAIL PROTECTED]
                  Website: http://www.delphi.org.nz

Reply via email to