Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Patterns and custom treeview nodes 1

Status
Not open for further replies.

golcarlad

Programmer
Nov 23, 2004
232
GB
What a waste of time today has been - so depressed!! Just tried implementing "Replace Type Code With Subclass" pattern (Martin Fowler) - on my code and it just made it worse - so in light of this I am going to try and ask you guys what I perhaps should have done.

I have a treeview with custom nodes I am adding to it. I have created 3 classes, (one inheriting TreeNode).

1 class in pretty generic (the one that inherits Treenode), the other 2 inherit this class with some peculiarities of their own.

I make an object of one of 3 types as and when necessary and add to the treeview. No problem here as they all have a base TreeNode.

When comes the time to iterate through the nodes I have problems in code elegance - I keep having to query the object to see what type it is - this causes a lot of switch/case statements everywhere and will only get worse the more custom nodes I add over time (requirements change as we all know!) - so what patterns should I be looking at? How can I make my code more easier to maintain - I just know it can be so much better (grrrrr!)

Any help much appreciated

Regards
 
ummmmmmmm..... what kind of specifics are you putting into your tree nodes?

You may be able to create a more generic baseclass or implement an interface on all of your subclasses.

the other option is to skip iterating through your treeview all together. Simply setup some keyvalue pairs (hashtable etc) that points from your nodes to your subnodes.

Or - look into link lists but this part gets ugly :)
 
Just some properties and some overridden methods to do stuff that the other class doesnt do.

I think if I create a generic baseclass or interface this will end up being huge, with half the functionality not be used in some cases.

Do you think we could summarise this situation by saying that generally - its a bad idea to add more than one type of object to a treeview - in effect it should be strongly typed to one object and thats that?
 
As far as I know a treeview is a simple view where a treenode has an icon and some text. If you want to show more complex things you should try a datagridview or some 3rd party datagrid which shows your data in a hirearchial manner.

And remember interfaces can implement other interfaces.

Christiaan Baes
Belgium

"My new site" - Me
 
OK - have now amalgamated all 3 classes into a megaclass - it has a constructor which defines an enum to indicate what type of node it is. This is basically back to what I had designed in the initial sketching out of code - so its a bit depressing to come back full circle. I still have to query for its enum type to decide what I should do with this node - so code bloat returns - ahhhhh!

PS - I dont think a datagridview is going to show my information in a clear way - a gives me a better UI design solution in this case, but thanks for the input.
 
have you looked into recursion? Instead of iterating through treenodes, and using switch statements to decide what to do with each, just create functions in your base class that just call the same function of all child nodes.

For example, I have a program that has a TreeView next to an Image, each node of the tree either does something to the image (draws a polygon, fills a polygon, shades an area, etc) and some do nothing, but can contain child nodes that do.

In my base class I have:
Code:
public virtual void OutputImage(Graphics g)
{
   // Fire each child node
   for(int i = 0; i < Nodes.Count; i++)
   {
     ((MyNodeBase)Nodes[i]).OutputImage(g);
   }
}

Then in nodes that dont do anything to the image, I dont have to do anything, the above code automatically calls all the child nodes for it.

In nodes that do however do something with the image, I just override the OutputImage method. i.e.
Code:
public override void OutputImage(Graphics g)
{
    g.DrawPolygon(.....);
    base.OutputImage(g);
}

So all I have to do in my form whenever I want to redraw the image is fire the root node's OutputImage method... something like this:
Code:
Graphics g = Graphics.FromImage(myPictureBox.Image);
((myNodeBase)myTreeView.Nodes[0]).OutputImage(g);
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top