如何设置表单客户区的最小尺寸。
该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.Size
和Form.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.Size
和Form.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
...