【问题标题】:Unknown behaviour in winformswinforms 中的未知行为
【发布时间】:2013-05-28 16:37:01
【问题描述】:

我正在使用此代码来隐藏表单的最小化/最大化控件并且只显示边框

protected override System.Windows.Forms.CreateParams CreateParams
{
    get
    {
        var parms = base.CreateParams;

        parms.Style &= ~0x00C00000; // remove WS_CAPTION
        parms.Style |= 0x00040000;  // include WS_SIZEBOX
        return parms;
    }
}

Visual Studio 中的表单如下所示

运行应用程序后,它看起来像这样

您可以看到,当我运行应用程序时,与应用程序右侧相比,应用程序左侧的空间更多。我被卡住了,不知道这种行为。

【问题讨论】:

  • 在您的设计截图上,“您要安装”标签下方是什么?
  • 我在这个标签下面有进度条。
  • 让我检查一下先生
  • 您是否尝试过将最小宽度设置为完全适合您想要的东西?
  • 坏主意,窗口大小取决于视频适配器的 DPI 设置。

标签: c# winforms


【解决方案1】:

发生这种情况的原因是定义窗体宽度和高度的Form.Size 属性包括窗口的边框大小。在表单设计器中,没有定义边框,因此您可以看到整个表单的布局。但是,当窗口由 Windows 呈现时,添加的边框会根据指定的大小进行计数。

为了解决这个问题,在加载或显示表单时,您可以将窗口大小添加为边框大小值的两倍。您可以通过P/InvokingGetSystemMetrics Win32 API function 使用SM_CXSIZEFRAME (32) 作为检索宽度的参数或SM_CYSIZEFRAME (33) 作为检索高度的参数检索该边框大小。

以下是您要查找的内容:

[DllImport("user32.dll")]
private static extern int GetSystemMetrics(int index);

private static int WindowBorderWidth
{
    get { return GetSystemMetrics(32); }
}

private static int WindowBorderHeight
{
    get { return GetSystemMetrics(33); }
}

protected override void OnLoad(EventArgs e)
{
    int increaseWidth = WindowBorderWidth * 2;
    int increaseHeight = WindowBorderHeight * 2;

    this.Size = new Size(
        this.Size.Width + increaseWidth,
        this.Size.Height + increaseHeight
    );
}

【讨论】:

  • 这很好用,但我在表单加载时更新标签文本,现在在表单加载时标签文本没有更新。
  • 感谢我将表单加载代码放在此函数protected override void OnLoad 中,现在它可以完美运行了。
  • OP 显然是为 4.5 之前构建的,否则问题一开始就不会发生。
【解决方案2】:

我无法准确地重现这一点。第一个可能的问题是这看起来像一个继承的表单,如果基本表单中的控件在底部或右侧锚点打开的情况下设置了锚点,这可能会导致麻烦。它根据基本表单的大小而不是继承的表单来定位控件。通过仅打开派生形式的锚点来解决此问题。

第二个也是更可能的问题是您正在与 Aero 中的 appcompat 问题作斗争。粗边框是 Aero 中的一个重要问题,因为应用程序指定了外部窗口大小。但真正关心的是内部窗口大小,客户矩形的大小。如果 Aero 不处理此问题,则窗口最终会导致客户区太小,无法为控件留出足够的空间。它通过撒谎窗口大小来做到这一点,秘密地使其大于应用程序要求的大小。然后在您询问尺寸时撒谎,报告的尺寸比窗口实际尺寸小。

您的 CreateParams 覆盖因非标准窗口样式而关闭的轮次。相应地,窗口的客户区会随着边框变宽而变小,默认为 6 个像素。

这个谎言会导致许多其他微妙的问题,例如难以对齐窗口。这个问题最终在 .NET 4.5 中得到解决,这是第一个不再需要支持 XP 的 .NET 版本。因此不再需要谎言。它将您的程序的 EXE 文件标记为需要 Vista 或更高版本。这可以消除谎言。

从你的问题中不清楚你想走哪条路。在这种情况下,最好只强制窗口的大小。您可以在表单的 OnLoad() 方法中执行此操作,如下所示:

    protected override void OnLoad(EventArgs e) {
        this.ClientSize = new Size(NoButton.Right + 10, NoButton.Bottom + 10);
        base.OnLoad(e);
    }

【讨论】:

  • 我得到 StackOverflow 异常 :) An unhandled exception of type 'System.StackOverflowException' occurred in System.Windows.Forms.dll
  • 在这一行this.ClientSize = new Size(buttion1.Right + 10, button1.Bottom + 10);
  • 您打电话给base.OnLoad(e)this.Onload(e) 还是只是OnLoad(e)base 部分非常重要,以确保您打电话给父母而不是打电话给自己,并且不能从通话中删除。
  • 我打电话给base.OnLoad(e); 这不是继承形式
  • 好吧,不知道,从这里看不到您的代码。然后只需使用 Load 事件即可。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-03
  • 1970-01-01
  • 1970-01-01
  • 2020-07-24
  • 2016-10-05
  • 2020-05-19
相关资源
最近更新 更多