Draw a scrolling family tree in C#


[family tree]

The example Draw a family tree in C# shows how to draw a family tree. Unfortunately if the tree is too big, you can’t make the form big enough to display it all.

One solution would be to use smaller images so everything will fit. This example shows a different approach. It moves the tree into a Panel control to make a scrolling family tree.

The previous solution draws the family tree centered on a PictureBox. The PictureBox is docked to the form so when you make the form bigger the PictureBox gets bigger, too. The problem occurs when you can’t make the form big enough to show the whole tree.

This example makes the following changes to create a scrolling family tree.

  • The form now contains a Panel control with:
    • AutoScroll = true. When the control’s contents (the PictureBox won’t fit, the Panel automatically displays scroll bars.
    • Dock = Fill. The Panel is docked to fill the form so when the form resizes the Panel does, too.
  • The PictureBox is now contained inside the Panel control. It has:
    • Dock = None. It does not resize when its container (the Panel) resizes.
    • ScaleMode = AutoSize. It resizes to fit its contents, which will be a Bitmap.
    • Location = (0, 0). That places the PictureBox in the Panel control’s upper left corner.

The previous version of the program drew the tree in the PictureBox control’s Paint event handler. This example draws it when the form loads. The following code shows the DrawTree method that draws the tree.

// Draw the tree on a Bitmap sized to fit.
private Bitmap DrawTree(TreeNode<PictureNode> root, int margin)
{
    float xmin = margin, ymin = margin;

    // Make a small bitmap so we can use its graphics handle.
    using (Bitmap bm = new Bitmap(10, 10))
    {
        using (Graphics gr = Graphics.FromImage(bm))
        {
            // Arrange the tree to see how big it is.
            root.Arrange(gr, ref xmin, ref ymin);
        }
    }

    // Make the result bitmap.
    int wid = (int)xmin + margin;
    int hgt = (int)ymin + margin;
    Bitmap result_bm = new Bitmap(wid, hgt);
    using (Graphics gr = Graphics.FromImage(result_bm))
    {
        // Draw the tree.
        gr.SmoothingMode = SmoothingMode.AntiAlias;
        gr.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
        root.DrawTree(gr);
    }

    return result_bm;
}

The code first creates a small Bitmap so it can use it to make a Graphics object. It then calls the root node’s Arrange method to make the tree arrange itself. After the call to Arrange, the xmin and ymin variables hold the tree’s right- and bottom-most coordinates. (They represent the minimum X and Y values that a new part of the tree could have if you were going to add to the tree.)

Now that the method knows how big the tree needs to be, it creates a Bitmap sized to fit. It creates a Graphics object for the Bitmap and calls the root node’s DrawTree to draw the tree on the Bitmap. The tree’s nodes draw themselves in the positions calculated by the earlier call to Arrange.

The following code shows how the main program uses the DrawTree method.

// Make the Panel display scroll bars if needed.
panScroller.AutoScroll = true;

// Draw the tree into a Bitmap and
// display the result in the PictureBox.
picTree.Location = new Point(0, 0);
picTree.SizeMode = PictureBoxSizeMode.AutoSize;
picTree.Image = DrawTree(root, 5);

The code sets the Panel control’s AutoScroll property so it displays scroll bars as needed. It then positions the PictureBox in the Panel control’s upper left corner and sets its SizeMode property to it resizes to fit its image. Finally it sets the PictureBox control’s Image equal to the Bitmap returned by the DrawTree method.

After that everything is automatic. The Panel displays scroll bars if needed and the PictureBox redraws its Image if necessary. There’s no need for a Paint event handler.

Both versions of the program have a MouseClick event handler that displays the name of people in the tree when you click on them. The new version is exactly the same as the old one. Even if you scroll the tree, the MouseClick event handler knows what point on the PicturyeBox you clicked so you don’t need to change the code to account for the scrolling.

This is a common technique for displaying large images. Use a PictureBox with ScaleMode = AutoSize and make it display a Bitmap. Place that inside a Panel with AutoScroll = true.

Download the example to see additional details.


Download Example   Follow me on Twitter   RSS feed   Donate




About RodStephens

Rod Stephens is a software consultant and author who has written more than 30 books and 250 magazine articles covering C#, Visual Basic, Visual Basic for Applications, Delphi, and Java.

This entry was posted in algorithms, classes, generic, graphics, OOP and tagged , , , , , , , , , , , , , , , , , , , , , . Bookmark the permalink.

One Response to Draw a scrolling family tree in C#

  1. maxy says:

    i like it.

Leave a Reply

Your email address will not be published. Required fields are marked *