【问题标题】:Two form with the same Location but different Position in the screen两个窗体在屏幕中具有相同的位置但不同的位置
【发布时间】:2020-06-23 07:24:37
【问题描述】:

我在form1中新建了一个form2,设置form2.Location = form1.Location。程序运行时,它们显示在屏幕的不同位置,但它们的Location.X 完全相同。而且这两个X之间有9个像素的区别。太奇怪了。

当我设置overlay.Location = new Point(this.Location.X, this.Location.Y + (Height - ClientSize.Height));

当我设置overlay.Location = new Point(this.Location.X + 9, this.Location.Y + (Height - ClientSize.Height) - 9);

这是代码。

表格1

public partial class Form1 : Form
{
    bool isOverlayGenerated = false;
    TestForm overlay = new TestForm();
    public Form1()
    {
        InitializeComponent();
        VisibleChanged += Form1_VisibleChanged;
        overlay.Size = ClientSize;
        overlay.ShowOnMeMo += () =>
        {
            overlay.memoEdit1.EditValue = $"form1: ({Location.X}, {Location.Y})";
            overlay.memoEdit1.EditValue += Environment.NewLine + $"form2: ({overlay.Location.X}, {overlay.Location.Y})";
        };
        overlay.Owner = this;
    }

    private void Form1_VisibleChanged(object sender, EventArgs e)
    {
        if (!isOverlayGenerated)
        {
            overlay.Location = new Point(this.Location.X, this.Location.Y + (Height - ClientSize.Height));
            //overlay.Location = new Point(this.Location.X + 9, this.Location.Y + (Height - ClientSize.Height) - 9);
            isOverlayGenerated = true;
            overlay.Show();
        }
    }
}

表格2

public partial class TestForm : DevExpress.XtraEditors.XtraForm
{
    public delegate void DoAThing();
    public event DoAThing ShowOnMeMo;
    public TestForm()
    {
        InitializeComponent();
    }

    private void simpleButton1_MouseClick(object sender, MouseEventArgs e)
    {
        ShowOnMeMo?.Invoke();
    }
}

【问题讨论】:

  • 坐标不同是因为你的overlay表单没有非客户区(你关闭了系统标题栏和窗口边框)。您需要调整坐标以解决该差异。 (不要对差异进行硬编码,因为它们因每个 Windows 版本而异,而是使用 GetSystemMetrics:docs.microsoft.com/en-us/windows/win32/api/winuser/…
  • 有一个属性控制表单的显示方式:form1.StartPosition = FormStartPosition.Manual,参见this topic
  • @Dai 谢谢,这是正确的答案。我确实找到了带有参数SM_CYCAPTION 的标题栏的高度,但是在打印了GetSystemMetrics() 的所有结果后,我找不到非客户端的宽度或高度。但我确实找到了另一种方法来确保使用Form.BoundsSystemInformation.CaptionHeight 来确保正确的非客户端大小。我将代码显示为答案

标签: c# winforms


【解决方案1】:

感谢@Dai 的回答,我找到了解决这个问题的方法。

int nonclientWidth = Bounds.Width - ClientSize.Width, nonclientHeight = (Bounds.Height - SystemInformation.CaptionHeight) - ClientSize.Height;
overlay.Location = new Point(this.Location.X + nonclientWidth / 2, this.Location.Y + SystemInformation.CaptionHeight + nonclientHeight / 2);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-17
    • 2020-12-29
    • 1970-01-01
    • 2020-09-11
    • 2012-10-25
    • 1970-01-01
    相关资源
    最近更新 更多