Form with a MainMenu shrinks every time the project is run
Asked Answered
K

2

2

Whenever I build the following program Form1's size shrinks by 20. (In some cases I need to make a change to the form, such as moving someLaggyControl1 by a few pixels, but not always. It's weird.) The form uses a MainMenu for the menu, not a MenuStrip. Yes, MainMenu is older and not recommended for use, but I need to use it for several reasons, one of which being radio-button items. Changing to a MenuStrip isn't a valid solution for me.

Here's the code needed to reproduce this issue:

Form1.designer.cs

namespace MainMenuMCVE
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing) {
            if (disposing && (components != null)) {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent() {
            this.components = new System.ComponentModel.Container();
            this.MainMenu1 = new System.Windows.Forms.MainMenu(this.components);
            this.menuItem1 = new System.Windows.Forms.MenuItem();
            this.menuItem2 = new System.Windows.Forms.MenuItem();
            this.menuItem7 = new System.Windows.Forms.MenuItem();
            this.menuItem8 = new System.Windows.Forms.MenuItem();
            this.menuItem3 = new System.Windows.Forms.MenuItem();
            this.menuItem4 = new System.Windows.Forms.MenuItem();
            this.menuItem5 = new System.Windows.Forms.MenuItem();
            this.menuItem6 = new System.Windows.Forms.MenuItem();
            this.someLaggyControl1 = new MainMenuMCVE.SomeLaggyControl();
            this.SuspendLayout();
            // 
            // MainMenu1
            // 
            this.MainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menuItem1,
            this.menuItem5});
            // 
            // menuItem1
            // 
            this.menuItem1.Index = 0;
            this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menuItem2,
            this.menuItem3,
            this.menuItem4});
            this.menuItem1.Text = "Example";
            // 
            // menuItem2
            // 
            this.menuItem2.Index = 0;
            this.menuItem2.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menuItem7,
            this.menuItem8});
            this.menuItem2.Text = "Something";
            // 
            // menuItem7
            // 
            this.menuItem7.Index = 0;
            this.menuItem7.Text = "Another thing";
            // 
            // menuItem8
            // 
            this.menuItem8.Index = 1;
            this.menuItem8.Text = "Ect";
            // 
            // menuItem3
            // 
            this.menuItem3.Index = 1;
            this.menuItem3.Text = "Something else";
            // 
            // menuItem4
            // 
            this.menuItem4.Index = 2;
            this.menuItem4.Text = "A third thing";
            // 
            // menuItem5
            // 
            this.menuItem5.Index = 1;
            this.menuItem5.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menuItem6});
            this.menuItem5.Text = "Example 2";
            // 
            // menuItem6
            // 
            this.menuItem6.Index = 0;
            this.menuItem6.Text = "Blah";
            // 
            // someLaggyControl1
            // 
            this.someLaggyControl1.Laggyness = 1000;
            this.someLaggyControl1.Location = new System.Drawing.Point(12, 81);
            this.someLaggyControl1.Name = "someLaggyControl1";
            this.someLaggyControl1.Size = new System.Drawing.Size(268, 23);
            this.someLaggyControl1.TabIndex = 0;
            this.someLaggyControl1.Text = "someLaggyControl1";
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(292, 253);
            this.Controls.Add(this.someLaggyControl1);
            this.Menu = this.MainMenu1;
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.MainMenu MainMenu1;
        private System.Windows.Forms.MenuItem menuItem1;
        private System.Windows.Forms.MenuItem menuItem2;
        private System.Windows.Forms.MenuItem menuItem3;
        private System.Windows.Forms.MenuItem menuItem4;
        private System.Windows.Forms.MenuItem menuItem5;
        private System.Windows.Forms.MenuItem menuItem6;
        private System.Windows.Forms.MenuItem menuItem7;
        private System.Windows.Forms.MenuItem menuItem8;
        private SomeLaggyControl someLaggyControl1;
    }
}

SomeLaggyControl.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace MainMenuMCVE
{
    class SomeLaggyControl : Control
    {
        public int Laggyness { get; set; }

        protected override void OnPaint(PaintEventArgs e) {
            e.Graphics.DrawString("A laggy control that takes " + Laggyness + " ms to render", this.Font, Brushes.Black, 0, 0);
            System.Threading.Thread.Sleep(Laggyness);
            base.OnPaint(e);
        }
    }
}

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace MainMenuMCVE
{
    public partial class Form1 : Form
    {
        public Form1() {
            InitializeComponent();
        }
    }
}

Program.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace MainMenuMCVE
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main() {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

The key part of this is a Form, Form1, which contains a MainMenu that has a few MenuItems, one of which has several sub-MenuItems. It also contains SomeLaggyControl, which is (of course) used as an example. SomeLaggyControl takes 1 second to render and is used to emulate a bunch of controls so that the example doesn't get messy.

Whenever I run the program, Form1's size shrinks. I may need to make a change to the form for it to shrink (e.g. moving someLaggyControl1 about), or I may not; I believe this has to deal with the designer generating new code. Regardless, this results in a shrinking form.

Here's some pictures showing this in action:

The original appearance of the form, before building, with a size of 300 by 300.
The original appearance of the form, before building, with a size of 300 by 300.

After the first rebuild.  It's not obvious, but the size is now 300 by 280.  Check the scroll bar.
After the first rebuild. It's not obvious, but the size is now 300 by 280. Check the scroll bar.

After a second rebuild.  The form is now 300 by 260, and it's more obvious.
After a second rebuild. The form is now 300 by 260, and it's more obvious.

After a third rebuild.  Now that it's 300 by 240, the form is getting small.
After a third rebuild. Now that it's 300 by 240, the form is getting small.

After several more rebuilds, I am left with this pleasant 300 by 47 form.
The form is unable to shrink anymore (though it tries).
After several more rebuilds, I am left with this pleasant piece of easy to use 300 by 47 form. The form is unable to shrink anymore (though it tries).


My primary question is this: How can I stop my form from resizing (apart from switching to a MenuStrip)? I'm also interested in why this happens, but that's not too important.

Kwarteng answered 11/2, 2015 at 17:54 Comment(0)
S
2

There is something built-in to that old menu system that increases the size of the form by the height of the menu system when it gets attached to its Menu property when using the designer.

For a work-around, go in the Designer.cs file, comment out this line:

// this.Menu = this.MainMenu1;

Then, in the OnLoad override, reattach it:

protected override void OnLoad(EventArgs e) {
  base.OnLoad(e);
  this.Menu = MainMenu1;
}

The menu won't be visible in the designer unless you select it from the component tray below the form area. You will notice the menu becomes visible on the form, and your form's size will temporarily increase while the menu is visible. This seems to prevent your form from always sizing itself.

Sack answered 11/2, 2015 at 19:1 Comment(3)
I don't repro, but the shoe fits. Legacy menus were pretty unusual, they reduced the size of the client area of a window. ClientSize is a big deal in the Winforms designer.Mullion
Thanks, this works well. Is it possible that the reason why it messes up is because the menu is added after ClientSize is set in the designer.cs file, thus changing the size? That would explain why the designer is getting confused.Kwarteng
@Kwarteng As good of a guess as any. That menu you are using is old code — makes it look like 1998 called when you click on it. :-)Sack
S
0

You could try setting the minimumSize to the same as the size you want the form to be. So that the form should never go smaller than that but can go as big as it needs to be. So if you need the form to be 300,300 change the minimum size to 300,300 also.

Skeg answered 11/2, 2015 at 18:26 Comment(1)
This works pretty well, but I'm accepting the other answer as it explains why it happens. This is still a useful method though (and I upvoted).Kwarteng

© 2022 - 2024 — McMap. All rights reserved.