MaxWidth, MinWidth, Width and ActualWidth Properties in WPF

Introduction

All the properties for the WPF controls derive from the FrameworkElement class. From the names we can conclude that the Width specifies the width that we want to set for the control and the other two properties, MinWidth and MaxWidth, are the constraint properties for the width control. There can be some cases that we can encounter when using these properties and I would like to discuss them here.

Case 1

All the three are set and the Width is least among all three. In this specific case MinWidth will take the precedence since the set width is even lesser then the minwidth. For example in the following code snippet the width of the control after the layout upadate would be MinWidth
  1. MinWidth="50" Width="20" MaxWidth="2in"  

Case 2

All the three are set and the Width is maximum among all the three. In this specific case MaxWidth will take the precedence since the set width is maximum. For example in the following code snippet the rendered width of the control would be MaxWidth.
  1. MinWidth="50" Width="300" MaxWidth="2in"  

Case 3

All the three are set and the Width is within the constraint set by MinWidth and MaxWidth. In this specific case the Widths value will be set for the control. For example in the following code snippet the rendered width of the control would be the Width's value:
  1. MinWidth="50" Width="300" MaxWidth="2in"  

Case 4

Only MinWidth and MaxWidth are set. In this case the precedence would be given to the width of the contents if the MaxWidth of the control is greter than the contents width as in the following case the width of the control would be the width of “What is your name”.
  1. <Button Content="What is your name" x:Name="tb" HorizontalAlignment="Center" MinWidth="40" MaxWidth="300"/>  

But if the MaxWidth is less than the width of the contents then in that case the width would be the MaxWidth. As in the following case the width of the control would be set to 60.

  1. <Button Content="What is your name" x:Name="tb" HorizontalAlignment="Center" MinWidth="40" MaxWidth="60"/>  

Now I want to discuss one more property that we should be familiar with and that is ActualWidth. This property is set by the layout system after it is done with all the rendering. These values could be different from the Height and Width property that we define when creating a control.

As stated in the MSDN “Because ActualWidth or ActualHeigth are calculated values, you should be aware that there could be multiple or incremental reported changes to it as a result of various operations by the layout system. The layout system may be calculating required measure space for child elements, constraints by the parent element and so on.

I have found actual width property to be useful when we want to bind the width property for the control to the width of some other control in the following manner.

  1. <Button Content="What is your name" x:Name="tb" HorizontalAlignment="Center" MinWidth="40" MaxWidth="60"/>  
  2.   
  3. <Button Width="{Binding ElementName=tb,Path=ActualWidth}" Grid.Column="1" Height="{Binding ElementName=tb,Path=ActualHeight}"></Button>  

There are many cases when we need the width of the control at run time to create the layout for other controls. We really can't rely on the Width property of the control as we have seen in the previous scenarios where the Width is different from the actual width that the control acquires after the layout has been done. We cannot be sure about getting the ActualWidth of any control in the Window just after the InitializeComponent() method.

The ActualWidth property should only be retrieved after the LayoutUpdated event of the window is executed. We should have a handler attached to this event as shown below.
  1. public MainWindow()  
  2. {  
  3.    InitializeComponent();  
  4.    this.LayoutUpdated += MainWindow_LayoutUpdated;  
  5. }  
  6.   
  7. void MainWindow_LayoutUpdated(object sender, EventArgs e)  
  8. {  
  9.    // get the ActualHeight/ActualWidth of the control here  
  10. }  

Please note that I have taken an example of Width here in this article. All the scenarios are also applicable for the Height property also.