The Windows Forms have Size
and ClientSize
Properties. Windows Forms also have a MinimumSize
property that lets you set the smallest allowed size of the form. I am looking for a way to set the minimum ClientSize
of a form. I'm new to c# and I am unsure of the best way to do this.
It occurred to me that I could use the Form.SizeChanged
event to check and restrict the form size but this seemed messy and I am looking for another way of doing it.
Note: If the form border size is changed I want the Minimum Client Size to be maintained.
How to set a minimum Size of a Form's Client Area.
The Form.MinimumSize
property sets the minimum size of the Form as a whole, including the current borders, the Caption and the subtle internal padding that is applied when the Form is resized and a new Layout is performed (many factors determine this activity).
It may be imperceptible, because it's fast (and, usually, nobody cares), but the relation between the Form Size and the Client Size is not constant. It can change when the Form is resized, dragging its borders. Or a System event causes this to happen.
Plus, changing the System settings, in many departments (the properties of the Windows, the Theme, Dpi, Font size etc.), can determine a change in the relations between the Form size and the size of its client area.
The good thing is that the Form is aware of these changes and, when notified of a System event that alters the aspect of Windows in some way, re-performs its layout.
When this happens (and it can happen frequently, always when a Form is resized), the OnLayout method is called.
Overriding OnLayout, allows to update values that rely on the Window/Client area measures.
➨ It can be interesting to see what happens when System settings, affecting the aspect of the Windows, are changed while the application is running. In this specific context, how many times the
OnLayout
method is called and what the LayoutEventArgs properties are set to.
This all considered, we can create a public MinimumClientSize
Property.
We override OnLayout
and reset the Form.MinimumSize
to the new Form.MinimumClientSize
plus the difference between the Form.Size
and the Form.ClientSize
.
For example, if we need to keep the Client Area size to a minimum of (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);
}
If we add to the OnLayout
method:
Console.WriteLine($"ClientSize: {ClientSize}");
Console.WriteLine($"MinimumSize: {MinimumSize}");
Console.WriteLine($"Size: {Size}");
it becomes clear that the relation between Form.Size
and Form.ClientSize
is not always the same.
We could also calculate the difference between Size and ClientSize this way:
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;
These fixed measures are correct. In normal situations, they provides the same values.
Not always, though. Never, when a Form is resized to its MinimumSize.
Plus, we're only considering a Form with a 3d Border.
Well, we could also override WndProc
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With