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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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.
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?