Layout Manager in CSharp (COPY)

THIS IS A COPY OF http://www.csharphelp.com/2005/11/layout-managers-in-c TO AVOID GETTING LOST IN SPACE


Layout Managers In C#

22. Nov, 2005 by admin

Project LayoutSource_lo_30.zip 10.2 KB DOWNLOAD:LayoutSource_lo_30 - (Hits: 484, size: 10.24 kB)
Library Download + XML Documentation LayoutLibrary_lo_30.zip 12.0 KB (DOWNLOAD:LayoutLibrary_Io_30 - (Hits: 490, size: 9 kB))

Whenever a programmer sits down to design a GUI, he is faced with several problems unique to their design: visual appeal, scalability, resizability, ease of modification, etc. Layoutmanagers help to solve these problems by taking care of setting the size and location of layoutable objects. Add the fact that layoutmanagers themselves are layoutable, and all kinds of layout possibilities open up. Java programmers are familiar with the concept of the layout manager, however programmers coming to C# from other programming backgrounds might need some getting used to them. If you are from a Java background, then you should read the section on differences between layout managers in Java and my implementation in C#. If you are unfamiliar with layout managers, then continue on and read the section on layout managers in general.

What is a Layout Manager?

A layout manager is anything which is able to decide the size and position of layoutable objects and which is itself layoutable. They can be used in any situation, however they are most often used in Graphical User Interfaces. As anyone who has ever programmed a GUI can attest, it tends to be a hassle at best. Some oft he tools which have become available in recent years, most based upon Borland’s great C++ Builder series, have made GUI design easier, but even with these sophisticated tools, GUIs are still a complicated problem. For those who want to simplify this problem or want more direct control over layout, layout managers are the way to go. A layout manager gives a lot of power over design to the programmer, as almost any configuration is possible through the use of layout manager nesting and area management. In addition, it takes care of the nasty parts of GUI development (resizing, natural layout, scalability) and leaves you, the programmer, with more time to concentrate on the more interesting parts of your design. Read on to find out more about layout managers and how you can introduce them into your GUIs.

Layout Manager Differences between Java and C#

There are two main differences between layout managers in Java and my implementation of layout managers in C#. The first is that in Java, layout managers are relegated purely to the area of Graphical User Interfaces. In other words, the only things which can be laid out by a layout manager are Components. In my implementation, anything which implements the ILayoutable interface is able to be laid out. This opens up many interesting possibilities in the areas of graphics, map design, and such. The second difference is related to the first. Since layout managers in my implementation are not tied directly to GUI objects but rather to the abstract concept of laying out layoutable things, it is possible to have layout managers for distinct areas of a parent Control. You are able to denote a particular rectangle in a parent control and give it a layout manager and add sub controls to it. This, in addition with the standard layout manager manipulations you know from Java, gives you incredible power in GUI design.

How to Use the Layout Library

The Layout library, the implementation of layout managers which I am presenting in this article, will be familiarto former Java programmers, and hopefully easy to understand for those from other backgrounds. It is based around two interfaces, ILayoutable and ILayoutManager, which extends ILayoutable. The remainder of the library consists of implementations of these two interfaces to the specific problem of GUI design:

ControlBox

This is the base of the Control layout structure and works as a basic wrapper class for Controls.

ContainerBox

Inherits from ControlBox, but is able to add other ControlBoxes and lay them out.

AreaPane

Inherits from ContainerBox, but acts as a top level pane. It has a rectangle in which it lays out the different Controls which have been added to it.

ResizeablePane

Inherits from AreaPane. The only difference is that it always resizes to be the client size of its parent Control.

Also provided in the library are several sample layouts:

BorderLayout

Allows 5 different Layoutable objects, one in each of the north, south, east and west and one in the center. All the size components are compressed in size, north and south are as small as they can be vertically and as large as they can be horizontally. West and east are as small as they can be horizontally and as large as they can be vertically. The center Layoutable object fills all of the space that remains.

GridLayout

Takes a number of rows and columns and creates a grid to which the user can add Controls. Each member in the grid is made the same size and laid out from left to right down the rows in the order that they are added.

FlowLayout

Tries to add Controls in a horizontal line, once the line is too big for the width of the container, it starts a new line. It can be aligned to the left, center, or right of the container.

Using these classes in GUI creation is straight forward. When you create a Control which will contain other controls, you wrap it in a ContainerBox, set the box’s layout, and then add all of the child Controls to the box. The only containing Control which is not added to a ContainerBox is the top level Control (usually a Form) which is wrapped in either an AreaPane or a ResizeablePane. A ResizeablePane will take the shape of its parent Control, but an AreaPane will be the area which is specified.

This picture is a screenshot of a GUI developed using the Layout Library. The following code is the code for laying out the Controls, with the accessory parts replaced with comments.

public class CalculatorForm : Form
{
    public CalculatorForm()
    {
        Size = new Size(200, 250);
        Text = "Calculator"; 

        myCalculator = new Calculator();
        //This will be the top-level pane to which all other controls will be added
        //and which also resizes as the Form is resized.
        AreaPane controlPane = new ResizeablePane(this, ClientRectangle, new BorderLayout()); 

        myTextBox = new TextBox();
        myTextBox.Text = "0";
        //Notice that the control is added to the pane. ContainerBoxes will
        //add all controls which are added to them to their boxed control automatically.
        controlPane.Add(myTextBox, BorderLayout.Direction.North); 

        Panel p = new Panel();
        //Since buttonPane will have other controls added to it, it is wrapped in
        //a ContainerBox.
        ContainerBox buttonPane = new ContainerBox(p);
        addButtons(buttonPane); 

        Button clearB = new Button();
        clearB.Text = "Clear";
        clearB.Click += new EventHandler(clear);
        controlPane.Add(clearB, BorderLayout.Direction.South); 

        controlPane.Add(buttonPane, BorderLayout.Direction.Center);
    } 

    private void addButtons(ContainerBox pane)
    {
        pane.layoutManager = new GridLayout(4, 3);
        for(int i=1; i<10; i++){
            Button b = getDigitButton(i);
            pane.Add(b);
        }
        Button zero = getDigitButton(0);
        Button plus = getButton("+");
        Button minus = getButton("-");
        plus.Click += new EventHandler(action);
        minus.Click += new EventHandler(action);
        pane.Add(plus);
        pane.Add(zero);
        pane.Add(minus);
    }
    //private methods called by the constructor
    //
}

Enjoy using the Layout library. I hope that it will add a new depth to your GUI development.