0

In my C# WinForm application I have a tableLayoutPanel with only one row and two columns. The left column contains a TreeView, the right one another tableLayoutPanel which was set to Dock: Fill in the designer. I want to create several GroupBoxes programmatically that should use the full width of this second column also when the form is resized.

In the designer of Visual Studio it looks like this:

Designer View of my tableLayout Panel

But when the application runs, the GroupBoxes don't use the complete width and it looks like this:

Dock: Fill is not used

I'm using two methods to create the GroupBoxes (you can ignore the int values):

private void addDashboardRow(int i, int s)
{
     // Add one row to dashboardTableLayoutPanel
     sensorTableLayoutPanel.RowCount++;
     // Maybe this one is wrong, but SizeType.AutoSize doesn't work either
     sensorTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, 75f));
     sensorTableLayoutPanel.Controls.Add(createSensorGroupbox(i, s));
}
private GroupBox createSensorGroupbox(int i, int sen)
{
     GroupBox g = new GroupBox();
     //g.Width = 500;          // I don't want fixed sizes, height of 75px is sufficient
     //g.Height = 75;
     g.Dock = DockStyle.Fill;
     g.Text = "Sensor " + sen.ToString();

     // just one label as example...
     Label temp = new Label();
     temp.Text = "Temperature: ";
     temp.Location = new Point(5, 20);
            
     Label tempVal = new Label();
     tempVal.Text = "°C";
     tempVal.Location = new Point(5, 50);
     tempVal.Name = "Sensor" + sen.ToString() + "_temp";

     //[... more labels]
     g.Controls.Add(temp);
     g.Controls.Add(tempVal);

     return g;
}

My questions are:

  1. How can I fit the GroupBox into the complete width of the parent container?
  2. How can I delete all rows? E.g. when looking up the sensors during run time all GroupBoxes are dublicated, but everything should be created newly.
  3. Layout of the question: how should I format terms like TableLayoutPanel correctly in this forum? It's my second question here and I haven't found out, yet.

For the second question. Currently I'm using this method that doesn't do what I'm expecting:

private void clearDashboardTable()
{
     if (sensorTableLayoutPanel.Controls.Count == sensorList.Count) {
          //MessageBox.Show(sensorTableLayoutPanel.Controls.Count.ToString());
          foreach (Control con in sensorTableLayoutPanel.Controls)
          {
               sensorTableLayoutPanel.Controls.Remove(con);
               con.Dispose();
          }
          //sensorTableLayoutPanel.Dispose();
          sensorList.Clear();
     }
}

I commented out what I've tried so far in the above code or added additional comments. I used this topic to try to understand the basics of dynamic groupbox creation: Add Row Dynamically in TableLayoutPanel

IVSoftware
  • 5,732
  • 2
  • 12
  • 23
z3dd4
  • 5
  • 1

1 Answers1

0

One way to achieve the outcome you describe is to make a custom UserControl containing a docked GroupBox that contains a docked TableLayoutPanel.

user control designer

To adjust the width when the container changes, attach to the SizeChanged event of the parent.

public partial class CustomGroupBox : UserControl
{
    public CustomGroupBox() => InitializeComponent();
    protected override void OnHandleCreated(EventArgs e)
    {
        base.OnHandleCreated(e);
        if((Parent != null) &&!DesignMode)
        {
            Parent.SizeChanged += onParentSizeChanged;
        }
    }
    private void onParentSizeChanged(object? sender, EventArgs e)
    {
        if(sender is FlowLayoutPanel flowLayoutPanel)
        {
            Debug.WriteLine($"{flowLayoutPanel.Width}");
            Width = 
                flowLayoutPanel.Width - 
                SystemInformation.VerticalScrollBarWidth;
        }
    }
    public new string Text
    {
        get=>groupBox.Text;
        set=>groupBox.Text = value;
    }
}

Main Form

The main form is laid out similar to your image except to substitute a FlowLayoutPanel on the right side.

main form designer

Now test it out with this minimal code in the method that loads the Main Form:

public partial class MainForm : Form
{
    int _id = 0;
    public MainForm()
    {
        InitializeComponent();
        flowLayoutPanel.AutoScroll= true;
        for (int i = 0; i < 5; i++)
        {
            var customGroupBox = new CustomGroupBox
            {
                Text = $"Sensor {++_id}",
                Width = flowLayoutPanel.Width - SystemInformation.VerticalScrollBarWidth,
                Padding = new Padding(),
                Margin = new Padding(),
            };
            flowLayoutPanel.Controls.Add(customGroupBox);
        }
    }
}

resizing


Clear

An example of clearing the sensors would be to add a button and set a handler in the same Load method:

buttonClear.Click += (sender, e) => flowLayoutPanel.Controls.Clear();
IVSoftware
  • 5,732
  • 2
  • 12
  • 23
  • I will check tomorrow and let you know. But thanks. Your answer looks good, but might need some changes in my real live example. – z3dd4 Jan 30 '23 at 01:52
  • Thanks for letting me know! If you would find it helpful, feel free to [clone](https://github.com/IVSoftware/group-boxes-fill-parent-width.git) the code I used to test this answer from my GitHub repo. – IVSoftware Jan 30 '23 at 02:12
  • 1
    Quick notice (2AM in Germany, almost going to bed ;-) - I was using Visual Studio 2019 and your code didn't work, my changes neither. I've updated now to Visual Code 2022 and can confirm that your code does what I want. I will look later today how I can change my code. Thanks a lot for the Git repository. Much more as what I have expected. – z3dd4 Feb 02 '23 at 01:00
  • 1
    Thanks again. I redesigned my complete application, but now everything works, especially with the GroupBoxes - yes, I'm using another one in a different form. Working with custom user control was new for me, so thanks for this lesson as well. I will leave some credits once my project is finished - I will put it on Github, but there's a Youtube playlist about the project (https://www.youtube.com/watch?v=VK3Pj76e1gA&list=PLdIR8q_1oO5Du9xklO7tYyTcq_UK8M4-j), so I will add credits for your answer there in one of the next videos. Again: thanks a lot and take care ;-) – z3dd4 Feb 23 '23 at 23:51