Visually Located

XAML and GIS

In depth look at the Windows RelativePanel

Windows 10 released a lot of new functionality and controls. One of the new controls is the RelativePanel. This panel takes the great Grid panel and cranks it up to 11.

The Grid panel gives a lot of control with how you layout controls. You specify rows and columns of various heights and widths and then place controls within the grid and define the row and/or column through attached properties. Instead of rows/columns, the RelativePanel places controls relative to itself or other controls within it. Just like the Grid, the RelativePanel uses 16 different attached properties to define where elements should be placed. In fact, the RelativePanel has no additional properties or methods from a regular Panel. It only contains attached properties.

Aligning relative to the RelativePanel

The relative panel does not respect controls with traditional alignment via HorizontalAlignment and VerticalAlignment. Instead there are six new properties to define how an element should align relative to the RelativePanel. These properties are boolean values that specify if it should align.

The following table shows the new attached properties.

Attached Property Default value Horizontal/VerticalAlignment equivalent
RelativePanel.AlignBottomWithPanel false VerticalAlignment=”Bottom”
RelativePanel.AlignHorizontalCenterWithPanel false HorizontalAlignment=”Center”
RelativePanel.AlignLeftWithPanel true HorizontalAlignment=”Left”
RelativePanel.AlignRightWithPanel false HorizontalAlignment=”Right”
RelativePanel.AlignTopWithPanel true VerticalAlignment=”Top”
RelativePanel.AlignVerticalCenterWithPanel false VerticalAlignment=”Center”

 

You can combine these values just as you could with HorizontalAlignment and VerticalAlignment. If you would like to center a control in the panel:

<RelativePanel>
    <Border Width="100" Height="100" Background="Blue" 
            RelativePanel.AlignHorizontalCenterWithPanel="True"
            RelativePanel.AlignVerticalCenterWithPanel="True"/>
</RelativePanel>

Center

By themselves, these six new properties are not very exciting. They are equivalent to the HorizontalAlignment and VerticalAlignment properties. The awesomeness comes from aligning with other elements.

NOTE: If you are following along with the blog, you will notice the designer, in both Visual Studio and Blend, will only render elements with the above properties correctly. It will not render elements with the properties below correctly. You will need to run the application to see the layout.

Align relative to other elements

This is where the RelativePanel shines. With the Grid control you had to create many different rows and columns. You had to know the row and/or column of a particular control. Then you assign the row and/or column of a control you wanted next to the first. Here is an example displaying name of someone

<TextBlock Text="Name" Grid.Row="1" Grid.Column="1"/>
<TextBlock Text="Shawn Kendrot" Grid.Row="1" Grid.Column="2" Margin="12,0,0,0"/>

Here is how you would accomplish that with the RelativePanel

<TextBlock x:Name="NameText" Text="Name"/>
<TextBlock Text="Shawn Kendrot" RelativePanel.RightOf="NameText" Margin="12,0,0,0"/>

When you want to align one control to the right of another another, simple say so!

Let’s take a look at the 10 new attached properties that allow for relative placement of one control with another.

Above

Aligns an element vertically above another element. This alone will not place an element directly above an element.

<RelativePanel>
    <Border x:Name="ElementOne" Width="200" Height="200" Background="Red" 
            RelativePanel.AlignHorizontalCenterWithPanel="True"
            RelativePanel.AlignVerticalCenterWithPanel="True"/>
    <Border x:Name="ElementTwo" Width="100" Height="100" Background="Blue" 
            RelativePanel.Above="ElementOne"/>
</RelativePanel>
Above-Windows

AlignBottomWith

Vertically aligns the bottom of a control with the bottom of another control. This property will not affect the horizontal alignment of the control.

<RelativePanel>
    <Border x:Name="ElementOne" Width="200" Height="200" Background="Red" 
            RelativePanel.AlignHorizontalCenterWithPanel="True"
            RelativePanel.AlignVerticalCenterWithPanel="True"/>
    <Border x:Name="ElementTwo" Width="100" Height="100" Background="Blue" 
            RelativePanel.AlignBottomWith="ElementOne"/>
</RelativePanel>

BottomWith

AlignHorizontalCenterWith

Horizontally aligns the center of one control with the center of another control. This property will not affect vertical alignment of the control.

<RelativePanel>
    <Border x:Name="ElementOne" Width="200" Height="200" Background="Red" 
            RelativePanel.AlignHorizontalCenterWithPanel="True"
            RelativePanel.AlignVerticalCenterWithPanel="True"/>
    <Border x:Name="ElementTwo" Width="100" Height="100" Background="Blue" 
            RelativePanel.AlignHorizontalCenterWith="ElementOne"/>
</RelativePanel>

HorizontalCenterWith

AlignLeftWith

Horizontally aligns the left edge of the control with the left edge of another control. This will not affect vertical alignment.

<RelativePanel>
    <Border x:Name="ElementOne" Width="200" Height="200" Background="Red" 
            RelativePanel.AlignHorizontalCenterWithPanel="True"
            RelativePanel.AlignVerticalCenterWithPanel="True"/>
    <Border x:Name="ElementTwo" Width="100" Height="100" Background="Blue" 
            RelativePanel.AlignLeftWith="ElementOne"/>
</RelativePanel>

LeftWith

AlignRightWith

Horizontally aligns the right edge of the control with the right edge of another control. This will not affect vertical alignment.

<RelativePanel>
    <Border x:Name="ElementOne" Width="200" Height="200" Background="Red" 
            RelativePanel.AlignHorizontalCenterWithPanel="True"
            RelativePanel.AlignVerticalCenterWithPanel="True"/>
    <Border x:Name="ElementTwo" Width="100" Height="100" Background="Blue" 
            RelativePanel.AlignRightWith="ElementOne"/>
</RelativePanel>

RightWith

AlignTopWith

Vertically aligns the top edge of the control with the top edge of another control. This will not affect horizontal alignment.

<RelativePanel>
    <Border x:Name="ElementOne" Width="200" Height="200" Background="Red" 
            RelativePanel.AlignHorizontalCenterWithPanel="True"
            RelativePanel.AlignVerticalCenterWithPanel="True"/>
    <Border x:Name="ElementTwo" Width="100" Height="100" Background="Blue" 
            RelativePanel.AlignTopWith="ElementOne"/>
</RelativePanel>

TopWith

AlignVerticalCenterWith

Vertically aligns the center of one control with the center of another control. This will not affect horizontal alignment.

<RelativePanel>
    <Border x:Name="ElementOne" Width="200" Height="200" Background="Red" 
            RelativePanel.AlignHorizontalCenterWithPanel="True"
            RelativePanel.AlignVerticalCenterWithPanel="True"/>
    <Border x:Name="ElementTwo" Width="100" Height="100" Background="Blue" 
            RelativePanel.AlignVerticalCenterWith="ElementOne"/>
</RelativePanel>

VerticalCenterWith

Below

Vertically aligns an element below another element. This alone will not place an element directly below an element. This will align the top edge of one control with the bottom edge of another control.

<RelativePanel>
    <Border x:Name="ElementOne" Width="200" Height="200" Background="Red" 
            RelativePanel.AlignHorizontalCenterWithPanel="True"
            RelativePanel.AlignVerticalCenterWithPanel="True"/>
    <Border x:Name="ElementTwo" Width="100" Height="100" Background="Blue" 
            RelativePanel.Below="ElementOne"/>
</RelativePanel>

Below

LeftOf

Horizontally aligns the right edge of one control with the left edge of another control.

<RelativePanel>
    <Border x:Name="ElementOne" Width="200" Height="200" Background="Red" 
            RelativePanel.AlignHorizontalCenterWithPanel="True"
            RelativePanel.AlignVerticalCenterWithPanel="True"/>
    <Border x:Name="ElementTwo" Width="100" Height="100" Background="Blue" 
            RelativePanel.LeftOf="ElementOne"/>
</RelativePanel>

LeftOf

RightOf

Horizontally aligns the left edge of one control with the right edge of another control.

<RelativePanel>
    <Border x:Name="ElementOne" Width="200" Height="200" Background="Red" 
            RelativePanel.AlignHorizontalCenterWithPanel="True"
            RelativePanel.AlignVerticalCenterWithPanel="True"/>
    <Border x:Name="ElementTwo" Width="100" Height="100" Background="Blue" 
            RelativePanel.RightOf="ElementOne"/>
</RelativePanel>

RightOf

Combining properties

Combine the alignment properties for the true power of the RelativePanel. Align the side and top/bottom edges of a control with another for exact layout.

<RelativePanel>
    <Border x:Name="ElementOne" Width="200" Height="200" Background="Red" 
            RelativePanel.AlignHorizontalCenterWithPanel="True"
            RelativePanel.AlignVerticalCenterWithPanel="True"/>
    <TextBlock Text="Hello" Margin="12,0,0,0" 
               RelativePanel.RightOf="ElementOne" 
               RelativePanel.AlignTopWith="ElementOne"/>
    <TextBlock Text="World" Margin="12,0,0,0"
               RelativePanel.RightOf="ElementOne" 
               RelativePanel.AlignBottomWith="ElementOne"/>
</RelativePanel>

Combine

You can try combining multiple horizontal or vertical alignments. As you can imagine, trying to horizontally align with two or more properties will probably not work. It’s hard to align to the left of object one while also aligning right of another.

Precautions

It is possible for items to be rendered outside of the given area. Take the following example of an item aligned to the panels right, and another object aligned to the right of the first.

<RelativePanel>
    <Border x:Name="ElementOne" Width="200" Height="200" Background="Red" 
            RelativePanel.AlignRightWithPanel="True"/>
    <Border x:Name="ElementTwo" Width="100" Height="100" Background="Blue" 
            RelativePanel.RightOf="ElementOne"/>
</RelativePanel>

When this is rendered, the blue area will not be visible.

OffScreen

This is still the case if you limit the size of the RelativePanel. If an item is out of the panel, it will not render.

Layout cascades from one item to another. So if object one aligns with object two, and object three aligns with object two, if object one moves, then object two and three move along with it.

This new controls offers great possibilities. What will you create with it?

blog comments powered by Disqus