WPF - Trying to set the MinHeight of resizeable window based on its initial height

Mark W picture Mark W · Jan 6, 2011 · Viewed 10.7k times · Source

I am trying to set the MinHeight / MinWidth of a resizeable window based on its initial height (when SizeToContent="WidthAndHeight").

I have seen a couple of answers / solutions:

http://weblogs.asp.net/psheriff/archive/2010/01.aspx

Set form MinWidth and MinHeight based on child property

However:

  1. I am trying to use the MVVM pattern and would like to be able to achieve this in the xaml.

  2. I would also like to keep values such as MinHeight out of the ViewModel - I dont think they belong there as they tie a trivial part of the behaviour of the view to the viewmodel. This is something I would like to leave to the UX designer.

A solution I am struggling with is to use the following xaml / binding:

<Window
        ....
        x:Name="mainWindow"
        SizeToContent="WidthAndHeight" 
        ResizeMode="CanResizeWithGrip"
        MinHeight="{Binding ElementName=mainWindow, Mode=OneTime, Path=ActualHeight}"
>

I would hope that 'Mode=OneTime' would bind the MinHeight to the initial value of the windows height.

But it does not work..

Can someone please explain why? Is there a solution that meets my criteria?

Thanks,

Mark

Answer

Nawaz picture Nawaz · Jan 6, 2011

Your code:

<Window
        ....
        x:Name="mainWindow"
        SizeToContent="WidthAndHeight" 
        ResizeMode="CanResizeWithGrip"
        MinHeight="{Binding ElementName=mainWindow, Mode=OneTime, Path=ActualHeight}"
>

It will not work, because the default value of ActualHeight is zero, and by the time WPF framework resizes your window, it already have assigned MinHeight with the default value of ActualHeight which is zero!

First thing you can try is this: change Mode=OneTime to Mode=Default, so that WPF could update MinHeight when ActualHeight gets changed on resizing the window. If that works, then you'll be happy.

Otherwise, you've to handle the SizeChanged event, and in the handler you can update the MinHeight.

<Window
            ....
            x:Name="mainWindow"
            SizeToContent="WidthAndHeight" 
            ResizeMode="CanResizeWithGrip"
            SizeChanged="Window_SizeChanged"
 >

In the code-behind:

bool firstTime= true;
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
     FrameworkElement  element = sender as FrameworkElement;
     if ( firstTime)
     {
            element.MinHeight = e.NewSize.Height;
            firstTime= false;
     }
}

Hope it will solve your problem. Or atleast will give you some idea as to how to proceeed. If you want to fix the size of your window, then you can also set the MaxHeight in the Window_SizeChanged() handler.


XAML ONLY SOLUTION

<Window
        x:Name="mainWindow"
        SizeToContent="WidthAndHeight" 
        ResizeMode="CanResizeWithGrip"
 >
 <Window.Triggers>
 <EventTrigger RoutedEvent="SizeChanged">
    <BeginStoryboard>
      <Storyboard Storyboard.TargetName="mainWindow">
            <DoubleAnimation Storyboard.TargetProperty="MinHeight" 
                             To="{Binding ElementName=mainWindow, Path=ActualHeight}"/>
       </Storyboard>
    </BeginStoryboard>
 </EventTrigger>
 </Window.Triggers>
 <!---- other code goes here--->
 </Window>