#332 – HorizontalContentAlignment and VerticalContentAlignment Are Sometimes Not Relevant

The HorizontalContentAlignment and VerticalContentAlignment properties, used to align a control’s content within the interior of the control, only make sense if the control is not automatically sizing to fit its content.

In the example below, all three buttons have their HorizontalContentAlignment property set to Right.  The first button has the default value for its HorizontalAlignment property (Stretch), so you can see the content of the button aligned to the right.  The other two buttons are not stretched, so their width is set to fit their content.  For these buttons, setting the HorizontalContentAlignment property doesn’t have any visible effect.

    <StackPanel>
        <Button Content="HorizontalAlignment=Stretch (Default)" HorizontalContentAlignment="Right"/>
        <Button Content="HorizontalAlignment=Left" HorizontalAlignment="Left" HorizontalContentAlignment="Right"/>
        <Button Content="HorizontalAlignment=Right" HorizontalAlignment="Right" HorizontalContentAlignment="Right"/>
    </StackPanel>

#331 – Default Values for HorizontalContentAlignment and VerticalContentAlignment

Controls have different default values for the HorizontalContentAlignment and VerticalContentAlignment properties, reflecting the most typical location within the control to place its content.

Default values for HorizontalContentAlignment / VerticalContentAlignment for the most common controls are listed below.

  • Button – Center, Center
  • Calendar – Left, Top
  • CheckBox – Left, Top
  • ComboBox – Left, Top
  • ContextMenu – Left, Center
  • DataGrid – Left, Top
  • DatePicker – Stretch, Top
  • Expander – Stretch, Stretch
  • GroupBox – Left, Top
  • Label – Left, Top
  • ListBox – Left, Center
  • Menu – Left, Top
  • PasswordBox – Left, Top
  • ProgressBar – Left, Top
  • RadioButton – Left, Top
  • RepeatButton – Center, Center
  • RichTextBox – Left, Top
  • Slider – Left, Top
  • StatusBar – Left, Top
  • TabControl – Center, Center
  • TextBox – Left, Top
  • TreeView – Left, Center

#330 – HorizontalContentAlignment and VerticalContentAlignment

Recall that the HorizontalAlignment and VerticalAlignment properties specify how child controls should be located and sized within their parent container.

The HorizontalContentAlignment and VerticalContentAlignment properties are similar, but specify how a control’s content should be aligned, within the interior of the control.

Below is an example of some non-default values for HorizontalContentAlignment.

    <StackPanel>
        <Label Content="Buttons:" FontWeight="Bold"/>
        <Button Content="Center (Default)"/>
        <Button Content="Left" HorizontalContentAlignment="Left"/>
        <Button Content="Right" HorizontalContentAlignment="Right" />

        <Label Content="Labels:" FontWeight="Bold" Margin="0,20,0,0"/>
        <Label Content="Left (Default)" Background="Thistle"/>
        <Label Content="Center" HorizontalContentAlignment="Center" Background="Goldenrod"/>
        <Label Content="Right" HorizontalContentAlignment="Right" Background="PaleGreen"/>
    </StackPanel>

#329 – Principles of Layout in WPF

WPF uses a flow-based layout model by default, where child elements are placed in a container and explicitly positioned based on their content.  This is as opposed to coordinate-based layout, where controls are given specific sizes and positions.

Parent containers (deriving from Panel) are responsible for figuring out both the size and position of all of their child controls.

In general, we following the following layout principles in WPF:

  • Don’t give controls a specific size, but let them size to fit their content
  • Don’t give controls a specific location, but let the parent container position them
  • Layout containers can be nested inside of other layout containers

#328 – Controls that Make Use of the Padding Property

The Padding property will add space within a control only if the control’s control template makes use of Padding.  Most, but not all, controls that derive from Control honor the Padding property.

Controls that make use of Padding:

  • Button
  • CheckBox
  • ComboBox
  • ContextMenu
  • DataGrid
  • DatePicker
  • Expander
  • GroupBox
  • Label
  • ListBox
  • Menu
  • PasswordBox
  • RadioButton
  • RepeatButton
  • RichTextBox
  • StatusBar
  • TabControl
  • TextBox
  • TreeView

Controls that do not make use of Padding:

  • Calendar
  • ProgressBar
  • Slider

#327 – Provide Extra Space Within a Control Using Padding

While the Margin property allows adding extra space around the outside of a control, within its container, the Padding property allows adding space within a control.  The space is added inside the control, around its content.

In the example below, we have three Button controls who are set to size to their content (which includes the padding).  The first button uses a default padding of 0.  The second button uses a padding of 5 WPF units around each side and the third uses a padding of 20.

        <Button Content="Click Me" HorizontalAlignment="Center"/>
        <Button Content="Click Me" HorizontalAlignment="Center"
                Padding="5"/>
        <Button Content="Click Me" HorizontalAlignment="Center"
                Padding="20"/>

#326 – Specifying a Symmetrical Margin Using Two Arguments

You can set the Margin property on a control so that it has some extra room around its edges, within its container.

You can specify a value for the Margin property in XAML using either one, two or four integer values.  Using one value indicates the margin for each of the four sides of the control.  Using four values indicates the left/top/right/bottom margin values individually.

When you use two values in specifying the Margin, you are specifying a value to be used for the left and right margins, and a value to be used for the top and bottom margins.  So a value of 10,20 is identical to 10,20,10,20.

    
        
        
        
    

The value of 10,20 indicates that the left and right margins should both be 10 WPF units and top and bottom should both be 20.  Using the two-argument version results in symmetrical margins.

#325 – Specifying a Margin Value in Code

You can set the Margin property on a control so that it has some extra room around its edges, within its container.

You’ll typically set the values for Margin in XAML, but you can also set a Margin value in code.  The type of the Margin property is Thickness, which is a struct having fields for margins along the left, top, right and bottom of a control.

You can specify a value for Margin by creating a new instance of the Thickness structure.

            double left = 5.0;
            double top = 10.0;
            double right = 2.0;
            double bottom = 20.0;
            lblName.Margin = new Thickness(left, top, right, bottom);

#324 – Setting a Margin with Different Sizes on Each Edge

You can set the Margin property on a control so that it has some extra room around its edges, within its container.

In XAML, if you specify a single value for Margin, that value will be used as the margin (in WPF Units) along each edge of the control.

    <StackPanel>
        <Label Content="Hello there.." Margin="3"/>
        <Button Content="Click Me" Margin="5"/>
    </StackPanel>

You can also specify four different values for the Margin property, listing the margin along each edge of the control in the order: Left, Top, Right, Bottom.

    <StackPanel>
        <Label Content="Hello there.." Background="Goldenrod" Margin="5,10,2,20"/>
        <Button Content="Click Me"/>
    </StackPanel>

#323 – Provide Space Around StackPanel Children Using Margin

By default, StackPanel provides no extra space around the child controls that it contains, but packs them tightly.

    <StackPanel>
        <Label Content="Gene Autry the singing cowboy" Background="Pink"/>
        <Button Content="I Like Gene" />
        <Label Content="Roy Rogers" Background="Aqua"/>
        <Button Content="I Like Roy Rogers Yes I Do"/>
        <Label Content="Spade Cooley had a sad story" Background="DodgerBlue"/>
    </StackPanel>


You can specify a margin that should be used around the outside of each control using the Margin property.

    <StackPanel>
        <Label Content="Gene Autry the singing cowboy" Background="Pink" Margin="5"/>
        <Button Content="I Like Gene" Margin="5"/>
        <Label Content="Roy Rogers" Background="Aqua" Margin="5"/>
        <Button Content="I Like Roy Rogers Yes I Do" Margin="5"/>
        <Label Content="Spade Cooley had a sad story" Background="DodgerBlue" Margin="5"/>
    </StackPanel>

In this example, we used a single value whenever we set the Margin property.  This causes the container to add the specified margin (in WPF units) along all four sides of the child control.