创建 Form.MinimumClientSize 属性

Com*_*ght 2 .net c# forms winforms

Windows 窗体具有SizeClientSize属性。Windows 窗体还有一个MinimumSize属性,可让您设置窗体的最小允许大小。我正在寻找一种设置最小值的方法ClientSize表单的方法。我是 C# 的新手,我不确定这样做的最佳方法。

我突然想到我可以使用该Form.SizeChanged事件来检查和限制表单大小,但这看起来很混乱,我正在寻找另一种方法。

注意:如果表单边框大小发生变化,我希望保持最小客户端大小。

Jim*_*imi 5

如何设置表单客户区的最小尺寸。

Form.MinimumSize属性将 Form 的最小尺寸设置为一个整体,包括当前边框、Caption 和在调整 Form 大小和执行新布局时应用的细微内部填充(许多因素决定了此活动)。

它可能是难以察觉的,因为它很快(而且通常没人关心),但 Form Size 和 Client Size 之间的关系不是恒定的。当窗体被调整大小时,它可以改变,拖动它的边框。或者系统事件导致这种情况发生。

另外,在许多部门中更改系统设置(Windows 的属性、主题、Dpi、字体大小等),可以确定表单大小与其客户区大小之间关系的变化。

好消息是 Form 知道这些更改,并且当通知系统事件以某种方式改变 Windows 的方面时,重新执行其布局。
当这种情况发生时(它可能经常发生,总是在调整 Form 大小时),将调用 OnLayout方法。

覆盖 OnLayout,允许更新依赖于窗口/客户区度量的值。

? 看看在应用程序运行时更改影响 Windows 方面的系统设置会发生什么会很有趣。在此特定上下文中,OnLayout 调用该方法的次数以及LayoutEventArgs属性设置为什么

考虑到这一切,我们可以创建一个公共MinimumClientSize属性。
我们覆盖OnLayout并重置Form.MinimumSize为新Form.MinimumClientSize加之间的差异Form.SizeForm.ClientSize

例如,如果我们需要将客户区大小保持在最小值(500, 500)

private Size m_MinimumClientSize = new Size(500, 500);

public Size MinimumClientSize {
    get => m_MinimumClientSize;
    set { m_MinimumClientSize = value;
          PerformLayout();
    }
}

protected override void OnLayout(LayoutEventArgs e) {
    base.OnLayout(e); 
    MinimumSize = m_MinimumClientSize + (Size - ClientSize);
}
Run Code Online (Sandbox Code Playgroud)

如果我们添加到OnLayout方法中:

Console.WriteLine($"ClientSize: {ClientSize}");
Console.WriteLine($"MinimumSize: {MinimumSize}");
Console.WriteLine($"Size: {Size}");
Run Code Online (Sandbox Code Playgroud)

它变得清晰,之间的关系Form.SizeForm.ClientSize并不总是相同的。

我们还可以通过这种方式计算 Size 和 ClientSize 之间的差异:

 var borderSize = new Size(
    (SystemInformation.FrameBorderSize.Width * SystemInformation.BorderMultiplierFactor 
        + (SystemInformation.Border3DSize.Width * 2)) * 2, 
    (SystemInformation.FrameBorderSize.Height * SystemInformation.BorderMultiplierFactor 
        + (SystemInformation.Border3DSize.Height * 2)) * 2);

var captionSize = new Size(0, SystemInformation.CaptionHeight);

MinimumSize = MinimumClientSize + borderSize + captionSize;
Run Code Online (Sandbox Code Playgroud)

这些固定措施是正确的。在正常情况下,它们提供相同的值。
不过,并非总是如此。永远不会,当一个 Form 被调整到它的 MinimumSize 时。
另外,我们只考虑带有 3d 边框的表单。
好吧,我们也可以覆盖WndProc...