Что делает позицию Winform изначально устаревшей? - PullRequest
3 голосов
/ 14 июля 2009

Код ниже демонстрирует очень простую проблему; Я надеюсь, что мне просто не хватает настройки, которую кто-то может раскрыть.

Цель

(1) Запустить главную winform (MainForm).
(2) Нажмите кнопку, чтобы отобразить вторичную winform (ShadowForm), которая является полупрозрачной и должна точно перекрывать MainForm.

Что на самом деле происходит

Сценарий 1 : Запустите основную winform, затем нажмите кнопку: ShadowForm отобразится с правильным размером, но с неверным местоположением, ниже и вправо (как если бы оно было каскадным). Нажмите кнопку, чтобы снова закрыть ShadowForm. Нажмите кнопку еще раз, чтобы снова открыть ShadowForm, и теперь он находится в правильном положении, покрывая MainForm.

Сценарий 2 : Запустите основную winform, переместите ее, затем нажмите кнопку: ShadowForm отображается с правильным размером, но с неверным расположением (где MainForm была до перемещения). Нажмите кнопку, чтобы закрыть; нажмите еще раз, чтобы снова открыть, и теперь ShadowForm находится в правильном положении.

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);
        }
    }
}

1 Ответ

6 голосов
/ 14 июля 2009

Вы должны установить StartPosition в ручную, прежде чем указывать свое местоположение в первый раз.

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

или, как предложил Джоэл:

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