Docking Control

Resizing

Our first child control is called DockingResize and provides an area of the docking control that the user can drag for resizing. Notice that when the mouse is clicked the OnMouseDown remembers the current size of the parent DockingControl and the screen position of the mouse. This is necessary so that when the OnMouseMove is received it can calculate how far the mouse has been moved since it was pressed and so the new size of DockingControl. Also notice that it will set the cursor to indicate a resizing operation is allowed.

// A bar used to resize the parent DockingControl
class DockingResize : UserControl
{
    // Class constants
    private const int _fixedLength = 4;

    // Instance variables
    private Point _pointStart;
    private Point _pointLast;
    private Size _size;

    public DockingResize(DockStyle ds)
    {
        this.Dock = DockingControl.ResizeStyleFromControlStyle(ds);
        this.Size = new Size(_fixedLength, _fixedLength);
    }   

    protected override void OnMouseDown(MouseEventArgs e)
    {
        // Remember the mouse position and client size when capture occured
        _pointStart = _pointLast = PointToScreen(new Point(e.X, e.Y));
        _size = Parent.ClientSize;

        // Ensure delegates are called
        base.OnMouseDown(e);
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        // Cursor depends on if we a vertical or horizontal resize
        if ((this.Dock == DockStyle.Top) ||
            (this.Dock == DockStyle.Bottom))
            this.Cursor = Cursors.HSplit;
        else
            this.Cursor = Cursors.VSplit;

        // Can only resize if we have captured the mouse
        if (this.Capture)
        {
            // Find the new mouse position
            Point point = PointToScreen(new Point(e.X, e.Y));

            // Have we actually moved the mouse?
            if (point != _pointLast)
            {
                // Update the last processed mouse position
                _pointLast = point;

                // Find delta from original position
                int xDelta = _pointLast.X - _pointStart.X;
                int yDelta = _pointLast.Y - _pointStart.Y;

                // Resizing from bottom or right of form means inverse movements
                if ((this.Dock == DockStyle.Top) ||
                    (this.Dock == DockStyle.Left))
                {
                    xDelta = -xDelta;
                    yDelta = -yDelta;
                }

                // New size is original size plus delta
                if ((this.Dock == DockStyle.Top) ||
                    (this.Dock == DockStyle.Bottom))
                    Parent.ClientSize = new Size(_size.Width, _size.Height + yDelta);
                else
                    Parent.ClientSize = new Size(_size.Width + xDelta, _size.Height);

                // Force a repaint of parent so we can see changed appearance
                Parent.Refresh();
            }
        }

        // Ensure delegates are called
        base.OnMouseMove(e);
    }

The only other work needed in this class is the override of OnPaint that is used to draw the 3D appearance of the resizing bar itself. It uses static methods from the DockingControl to recover the correct GDI+ objects to use.

    protected override void OnPaint(PaintEventArgs pe)
    {
        // Create objects used for drawing
        Point[] ptLight = new Point[2];
        Point[] ptDark = new Point[2];
        Rectangle rectMiddle = new Rectangle();

        // Drawing is relative to client area
        Size sizeClient = this.ClientSize;

        // Painting depends on orientation
        if ((this.Dock == DockStyle.Top) ||
            (this.Dock == DockStyle.Bottom))
        {
            // Draw as a horizontal bar
            ptDark[1].Y = ptDark[0].Y = sizeClient.Height - 1;
            ptLight[1].X = ptDark[1].X = sizeClient.Width;
            rectMiddle.Width = sizeClient.Width;
            rectMiddle.Height = sizeClient.Height - 2;
            rectMiddle.X = 0;
            rectMiddle.Y = 1;
        }
        else if ((this.Dock == DockStyle.Left) ||
                 (this.Dock == DockStyle.Right))
        {
            // Draw as a vertical bar
            ptDark[1].X = ptDark[0].X = sizeClient.Width - 1;
            ptLight[1].Y = ptDark[1].Y = sizeClient.Height;
            rectMiddle.Width = sizeClient.Width - 2;
            rectMiddle.Height = sizeClient.Height;
            rectMiddle.X = 1;
            rectMiddle.Y = 0;
        }

        // Use colors defined by docking control that is using us
        pe.Graphics.DrawLine(DockingControl.LightPen, ptLight[0], ptLight[1]);
        pe.Graphics.DrawLine(DockingControl.DarkPen, ptDark[0], ptDark[1]);
        pe.Graphics.FillRectangle(DockingControl.PlainBrush, rectMiddle);

        // Ensure delegates are called
        base.OnPaint(pe);
    }
}

You might also like...

Comments

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“An idiot with a computer is a faster, better idiot” - Rich Julius