What makes Winform's position harden initially?

The code below shows a very simple problem; I hope that I just do not have a setting that anyone can identify.

purpose

(1) Run the main winform (MainForm).
(2) Click the button to display the secondary winform (ShadowForm), which is translucent and should exactly overlap the MainForm.

What is really going on

Scenario 1: Launch the main winform and click the button: ShadowForm displays with the correct size, but the wrong location, lower and to the right (as if it were cascading). Click the button to close ShadowForm again. Click the button again to open ShadowForm again, and now it is in the correct position, spanning MainForm.

Scenario 2. Run the main winform, move it, then click the button: ShadowForm displays with the correct size but the wrong location (where MainForm was before moving). Click the button to close; click again to open again, and now ShadowForm is in the correct position.

using System;
using System.Windows.Forms;

namespace LocationTest
{
    static class Program
    {
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }
    }

    public class MainForm : Form
    {
        ShadowForm shadowForm = new ShadowForm();
        Button button1 = new Button();
        System.ComponentModel.IContainer components = null;

        public MainForm()
        {
            this.SuspendLayout();
            this.button1.Location = new System.Drawing.Point(102, 44);
            this.button1.Size = new System.Drawing.Size(75, 23);
            this.button1.Text = "button1";
            this.button1.Click += new System.EventHandler(this.button1_Click);
            this.ClientSize = new System.Drawing.Size(292, 266);
            this.Controls.Add(this.button1);
            this.ResumeLayout(false);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (shadowForm.Visible) { shadowForm.Hide(); }
            else
            {
                shadowForm.Size = Size; // this always works
                shadowForm.Location = Location; // this fails first time, but works second time!
                shadowForm.Show();
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null)) { components.Dispose(); }
            base.Dispose(disposing);
        }
    }

    public class ShadowForm : Form
    {
        private System.ComponentModel.IContainer components = null;

        public ShadowForm()
        {
            this.SuspendLayout();
            this.BackColor = System.Drawing.Color.Black;
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            this.Opacity = 0.5;
            this.Click += new System.EventHandler(this.ShadowForm_Click);
            this.ResumeLayout(false);
        }

        private void ShadowForm_Click(object sender, EventArgs e)
        {
            Hide();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null)) { components.Dispose(); }
            base.Dispose(disposing);
        }
    }
}
+3
source share
1 answer

You must set StartPosition manually before setting your location for the first time.

shadowForm.StartPosition = FormStartPosition.Manual;
shadowForm.Size = Size; // this always works
shadowForm.Location = Location; // this fails first time, but works second time!
shadowForm.Show();

or as Joel suggested:

shadowForm.StartPosition = FormStartPosition.CenterParent;  // Location shouldn't need to be set
shadowForm.Size = Size; // this always works
shadowForm.Show();
+6
source

Source: https://habr.com/ru/post/1712586/


All Articles