2

I have a WinForm that has a TableLayoutPanel control. My code will detect the number of attached monitors on screen, create a column per monitor, and then add a button for each display within each individual column in the TableLayoutControl so I can ensure that no matter how many monitors are attached, the buttons will appear "centered" across the form. One/two monitors renders just fine, however three monitors results in end columns not being evenly distributed.

enter image description here

Here is my code:

            int count = Screen.AllScreens.Count();
            this.monitorLayoutPanel.ColumnCount = count;

            ColumnStyle cs = new ColumnStyle(SizeType.Percent, 100 / count);
            this.monitorLayoutPanel.ColumnStyles.Add(cs);

            this.monitorLayoutPanel.AutoSize = true;

            var buttonSize = new Size(95, 75);

            int z = 0;
            foreach (var screen in Screen.AllScreens.OrderBy(i => i.Bounds.X))
            {

                Button monitor = new Button
                {
                    Name = "Monitor" + screen,
                    AutoSize = true,
                    Size = buttonSize,

                    BackgroundImageLayout = ImageLayout.Stretch,                                                  
                    BackgroundImage = Properties.Resources.display_enabled,
                    TextAlign = ContentAlignment.MiddleCenter,
                    Font = new Font("Segoe UI", 10, FontStyle.Bold),
                    ForeColor = Color.White,
                    BackColor = Color.Transparent,
                    Text = screen.Bounds.Width + "x" + screen.Bounds.Height,
                    Anchor = System.Windows.Forms.AnchorStyles.None
                };


                this.monitorLayoutPanel.Controls.Add(monitor, z, 0);
                z++;
                monitor.MouseClick += new MouseEventHandler(monitor_Click);
            }

I've tried making the buttons smaller, and increased the form size but the last column is always smaller than the first two. I can't understand it!

Rawns
  • 865
  • 4
  • 27
  • 1
    [How to create a magic square using Windows Forms?](http://stackoverflow.com/q/33968993/3110834) – Reza Aghaei Oct 06 '16 at 09:06
  • [How to set FlowLayoutPanel contents at Center of Form](https://stackoverflow.com/questions/38824530/how-to-set-flowlayoutpanel-contents-at-center-of-form) – Reza Aghaei Oct 06 '16 at 09:14
  • To make your dynamic controls align at bottom-center of form, take a look at second linked post. You can add your button controls to an auto-sized `FlowLayoutPanel` which its anchor is set to `Top, Bottom` and is hosted in a single-column docked-to-button `TableLayoutPanel`. – Reza Aghaei Oct 06 '16 at 09:18
  • A single-cell `TableLayoutPanel` keeps the auto-sized contents at center if you use suitable anchor for contents (for example `None` or `Top, Bottom`): [Keep a Control vertically and horizontally at Center of Container](http://stackoverflow.com/a/39047133/3110834) – Reza Aghaei Oct 06 '16 at 09:25

2 Answers2

2

Clear ColumnStyles first.

this.monitorLayoutPanel.ColumnStyles.Clear();

then:

int count = Screen.AllScreens.Count();

for (int i = 0; i < count; i++)
{
    ColumnStyle cs = new ColumnStyle(SizeType.Percent, (float)100 / count);
    this.monitorLayoutPanel.ColumnStyles.Add(cs);
}

this.monitorLayoutPanel.AutoSize = true;

...
MSL
  • 990
  • 1
  • 12
  • 28
  • Thanks for the suggestion. It's made the last two columns more even, however all three the columns are still not evenly distributed: [screenshot](https://imgur.com/a/LJZBb) – Rawns Oct 06 '16 at 08:36
  • Maybe its because of float parameter. – MSL Oct 06 '16 at 09:18
  • @MSL Yes, `ColumnStyles` should be cleared at first. For this problem, I'd keep button-list in bottom-center of form [like this](https://stackoverflow.com/questions/38824530/how-to-set-flowlayoutpanel-contents-at-center-of-form). – Reza Aghaei Oct 06 '16 at 09:35
1

Reza Aghaei pointed me to this thread How to create a magic square using Windows Forms? which pointed me in the right direction. Updated (and working) code below. :)

            int screens = Screen.AllScreens.Count();
            this.monitorLayoutPanel.ColumnStyles.Clear();
            this.monitorLayoutPanel.ColumnCount = screens;            
            this.monitorLayoutPanel.AutoSize = true;

            int z = 0;
            foreach (var screen in Screen.AllScreens.OrderBy(i => i.Bounds.X))
            {
                var percent = 100f / screens;
                this.monitorLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, percent));

                Button monitor = new Button
                {
                    Name = "Monitor" + screen,
                    Size = new Size(95, 75),
                    BackgroundImageLayout = ImageLayout.Stretch,                                                  
                    BackgroundImage = Properties.Resources.display_enabled,
                    TextAlign = ContentAlignment.MiddleCenter,
                    Font = new Font("Segoe UI", 10, FontStyle.Bold),
                    ForeColor = Color.White,
                    BackColor = Color.Transparent,
                    Text = screen.Bounds.Width + "x" + screen.Bounds.Height,
                    Anchor = System.Windows.Forms.AnchorStyles.None
                };


                this.monitorLayoutPanel.Controls.Add(monitor, z, 0);
                z++;
                monitor.MouseClick += new MouseEventHandler(monitor_Click);
Community
  • 1
  • 1
Rawns
  • 865
  • 4
  • 27