I know for a Window
(any FrameworkElement
actually) you can specify a MinWidth
and MinHeight
. What I'm wondering is how I can make that minimum match the window's DesiredSize
?
In other words, I want to say 'You can resize this window as small as you want, but not smaller than the minimum needed to show its content.'
For instance, say I have a simple Window
containing a DockPanel
with three items in it arranged vertically. For simplicity, we'll only talk about the height.
The first is a
Rectangle
with aHeight
of 20 and is pinned to the top so itsDesiredSize.Height
is 20.The second is a
Label
which has aMinHeight
of 20 and is pinned to the bottom, but can grow in height if there are multiple lines of text. (Currently, there's only a single word so theDesiredSize.Height
is also 20)The third item is a custom
ImageViewer
control that fills the remaining area in the middle, but which will never be smaller than its content, plus its padding. Currently the image is 15x15 and the padding is 2.5 on a side so itsDesiredSize.Height
is 20 (2.5 + 15 + 2.5)
With the above, the DesiredSize.Height
for the StackPanel would thus be 60 (20 + 20 + 20), and the DesiredSize.Height
of the Window
would be that 60 + it's own chrome's height (let's just say that too is 20), and that seems to give me a Window.DesiredSize.Height
of 80. That's what I'm after for the MinHeight of the window.
I've tried binding The Window
's MinHeight
to its DesiredSize.Height
via a SizeToDoubleConverter
(that takes a Dimension
to determine to return the Width
or Height
accordingly) but it didn't have any effect.
This looks promising...
protected override Size MeasureOverride(Size availableSize) {
var desiredSize = base.MeasureOverride(availableSize);
MinWidth = Math.Ceiling(DesiredSize.Width);
MinHeight = Math.Ceiling(DesiredSize.Height);
return desiredSize;
}
Note: I tend to use Math.Ceiling
on the actual DesiredSize.Height
because it's usually a fraction and the layout will get thrown off when aligning to device pixels, messing things up.
The above is close to working, but you run into issues if you want to also set the MaxHeight
equal to it (for instance, to allow horizontal, but not vertical sizing.)
This kind of thing is easy with AutoLayout in iOS/macOS, but I'm not sure how to do this in WPF, even programmatically. I just have to keep guessing at what size looks best.
This is a good question. I've achieved the goal but it's not pretty. I wouldn't recommend this approach but it does what it says on the tin.
Bare bones, project called DynamicMinumumSize:
MainWindow.xaml.cs:
Xaml:
Converter:
Visualised: