Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

User Resizing of Row and Columns in TableLayoutPanel At Runtime

Tags:

c#

winforms

I'm working on a WinForm project and "trying" to create a TableLayoutPanel that the user can resize at runtime like the behavior of the SplitContainer. I've found some code that partially does this but it's incomplete. Can someone please help me out here?

Thanks in advance, -DA

This is the code I have so far that comes from a thread I found on CodeProject. The only thing different that I've done in my own is create a customTableLayoutPanel that inherits from TableLayoutPanel.

public partial class Form1 : Form
{
    bool resizing = false;
    TableLayoutRowStyleCollection rowStyles;
    TableLayoutColumnStyleCollection columnStyles;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        rowStyles = tableLayoutPanel1.RowStyles;
        columnStyles = tableLayoutPanel1.ColumnStyles;
    }

    private void tableLayoutPanel1_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            resizing = true;
        }
    }

    private void tableLayoutPanel1_MouseMove(object sender, MouseEventArgs e)
    {
        if (resizing)
        {
            columnStyles[0].SizeType = SizeType.Absolute;
            rowStyles[0].SizeType = SizeType.Absolute;
            rowStyles[0].Height = e.Y;
            columnStyles[0].Width = e.X;
        }
    }

    private void tableLayoutPanel1_MouseUp(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            resizing = false;
        }
    }
}
like image 741
Max Eisenhardt Avatar asked Jun 18 '13 20:06

Max Eisenhardt


2 Answers

Set Column SizeType and Row SizeType property as Absolute and CellBorderStyle as which ever you want rather than none after that in code write as below

public partial class Form1 : Form
{
    bool resizing = false;
    TableLayoutRowStyleCollection rowStyles;
    TableLayoutColumnStyleCollection columnStyles;
    int colindex = -1;
    int rowindex = -1;
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        rowStyles = tableLayoutPanel1.RowStyles;
        columnStyles = tableLayoutPanel1.ColumnStyles;
    }
    private void tableLayoutPanel1_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            rowStyles = tableLayoutPanel1.RowStyles;
            columnStyles = tableLayoutPanel1.ColumnStyles;
            resizing = true;
        }
    }

    private void tableLayoutPanel1_MouseMove(object sender, MouseEventArgs e)
    {
        if (!resizing)
        {
            float width = 0;
            float height = 0;
            //for rows
            for (int i = 0; i < rowStyles.Count; i++)
            {
                height += rowStyles[i].Height;
                if (e.Y > height - 3 && e.Y < height + 3)
                {
                    rowindex = i;
                    tableLayoutPanel1.Cursor = Cursors.HSplit;
                    break;
                }
                else
                {
                    rowindex = -1;
                    tableLayoutPanel1.Cursor = Cursors.Default;
                }
            }
            //for columns
            for (int i = 0; i < columnStyles.Count; i++)
            {
                width += columnStyles[i].Width;
                if (e.X > width - 3 && e.X < width + 3)
                {
                    colindex = i;
                    if (rowindex > -1)
                        tableLayoutPanel1.Cursor = Cursors.Cross;
                    else
                        tableLayoutPanel1.Cursor = Cursors.VSplit;
                    break;
                }
                else
                {
                    colindex = -1;
                    if (rowindex == -1)
                        tableLayoutPanel1.Cursor = Cursors.Default;
                }
            }
        }
        if (resizing && (colindex>-1 || rowindex > -1))
        {
            float width = e.X;
            float height = e.Y;
            if (colindex > -1)
            {
                for (int i = 0; i < colindex; i++)
                {
                    width -= columnStyles[i].Width;
                }
                columnStyles[colindex].SizeType = SizeType.Absolute;
                columnStyles[colindex].Width = width;
            }
            if (rowindex > -1)
            {
                for (int i = 0; i < rowindex; i++)
                {
                    height -= rowStyles[i].Height;
                }

                rowStyles[rowindex].SizeType = SizeType.Absolute;
                rowStyles[rowindex].Height = height;
            }
        }
    }

    private void tableLayoutPanel1_MouseUp(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            resizing = false;
            tableLayoutPanel1.Cursor = Cursors.Default;
        }
    }
}
like image 123
Mehul Patel Avatar answered Sep 21 '22 05:09

Mehul Patel


I improved the code of MD's answer.
Instead of listening to MouseEvents of the TableLayoutPanel I listen to those of the Controls. Here is the code for resizable rows:

    TableLayoutPanel tlp;
    bool resizing;
    int rowindex = -1;
    int nextHeight;

    private void control_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            resizing = true;
        }
    }

    private void control_MouseMove(object sender, MouseEventArgs e)
    {
        Control c = (Control)sender;
        if (!resizing)
        {
            rowindex = -1;
            tlp.Cursor = Cursors.Default;

            if (e.Y <= 3)
            {
                rowindex = tlp.GetPositionFromControl(c).Row - 1;
                if (rowindex >= 0)
                    tlp.Cursor = Cursors.HSplit;
            }
            if (c.Height - e.Y <= 3)
            {
                rowindex = tlp.GetPositionFromControl(c).Row;
                if (rowindex < tlp.RowStyles.Count)
                    tlp.Cursor = Cursors.HSplit;
            }
        }
        if (resizing && rowindex > -1)
        {
            nextHeight = e.Y;
        }
    }

    private void control_MouseUp(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            if (nextHeight > 0)
                tlp.RowStyles[rowindex].Height = nextHeight;
            resizing = false;
        }
    }
like image 45
Breeze Avatar answered Sep 20 '22 05:09

Breeze