I need to draw a large, interactive tree structure in C# WinForms - a corporate hierarchy.
Aside from the algorithm which will arrange the blocks in the tree which is probably going to be quite complex, I'm not really sure about how to go about implementing the actual canvas and drawing code.
At first glance, I could create a giant Image (or a matrix of largeish images), and use a Graphics
or BufferedGraphics
to render a small region given where the user is zoomed into. This would give the zooming and panning effect you might see on Google Maps.
As for interactivity, what can be done here? I'd like the user to be able to highlight certain people (people in a particular cost centre, people who are contractors, etc...). Also, it would be pretty cool if the tree showed progressively more information about the staff as the user is zoomed in more. Should I just be doing hit testing with the MouseMove
event and programatically add/remove/alter the things which make up the picture on the canvas?
Is this something that I should avoid using GDI for and maybe using DirectDraw instead? I don't want to go overkill - I just want to be able to visually represent the structure and give users the option to print it.
Alternatively, is there a (freeware?) library available which allows zooming and panning with interactivity? I might be asking a bit much, but maybe one which also can handle tree structures?
I have experience with each individual concept on a smaller scale, however nothing brought together in a largeish structure like this. I predict that if I do something wrong, it can turn into something very slow, laggy, and memory-hogging.
I've only dabbled in WPF. I almost exclusively use WinForms in .Net - is there something in WPF which would make this task significantly easier?
I don't know if this even is an answer, but I do a lot of interactive graphical work using GDI+ and I feel that I can work very effectivly with it. Both when it comes to tree structures exacly as the one you describe as well as versatile layout editors and over to browsing photos etc.
What you do not want is painting everything on a large bitmap. Avoid large bitmaps. :-)
So either you use double buffered graphics as provided by the framework or you design it on you own. This may not be perfect if you want to run your app remotely, however: http://blogs.msdn.com/b/oldnewthing/archive/2006/01/03/508694.aspx
Basically you just put everything you want to draw in a list and update it with inforamtion on exactly where it ended you on screen so that you can hit-test for it in OnMouseDown/OnMouseMove/OnMouseUp. You'll soon notice the need for keeping an enum for which state the interaction is in (eg.g DraggingObject, MakingSelection, Scrolling etc) and a Point _lastMousePosition.
The logic is pretty simple. Making it flicker-free and responsive may not be that simple.