Jeorge535
Jeorge535

Reputation: 33

How can I resize a resizable panel control at runtime from the left-hand side?

I have a custom user control in my program. It is a panel which needs to be resizable from the left-hand side. Here is my code:

private void ResizePanel_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left && e.X == ClientRectangle.Left)
    {
        resizeMode = true;
    }
}

private void ResizePanel_MouseUp(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        resizeMode = false;
    }
}

private void ResizePanel_MouseMove(object sender, MouseEventArgs e)
{
    if (resizeMode == true)
    {
        Size newSize = new Size();
        newSize.Height = Height;
        newSize.Width = Math.Abs(e.X - ClientRectangle.Left); // Distance between the mouse position and 
                                                              // left side of the panel

        if (e.X < this.ClientRectangle.Left)
        {
            Width = newSize.Width;
            Left -= newSize.Width;
        }
    }
}

In theory, the solution would be to move the panel to the left by the new width as the width increases. That's what this code is supposed to do. The problem with it at the moment is that as the panel moves to the left, the width stays the same and doesn't increase. Is there a way to do this so I can grab the control on the left side and drag to the left, so the size increases and it appears to stay in place?

Upvotes: 1

Views: 534

Answers (1)

Idle_Mind
Idle_Mind

Reputation: 39132

Here's a quick and dirty panel that can only be dragged from the left side:

class LeftSideResizePanel : Panel
{

    private const int HTLEFT = 10;
    private const int HTCLIENT = 1;        
    private const int WM_NCHITTEST = 0x0084;
    private const int WS_THICKFRAME = 0x40000;

    protected override CreateParams CreateParams
    {
        get
        {
            var cp = base.CreateParams;
            cp.Style |= WS_THICKFRAME;
            return cp;
        }
    }

    protected override void WndProc(ref Message m)
    {
        switch (m.Msg)
        {
            case WM_NCHITTEST:
                Point pt = this.PointToClient(new Point(m.LParam.ToInt32()));
                Rectangle hit = new Rectangle(new Point(-3, 0), new Size(6, this.Height));
                m.Result = hit.Contains(pt) ? (IntPtr)HTLEFT : (IntPtr)HTCLIENT;
                return;
        }

        base.WndProc(ref m);
    }

}

If you don't like the look that WS_THICKFRAME gives, you'll have to go for finer control using a method as described in Jimi's comment.

Upvotes: 1

Related Questions