We got a great new layout panel in Windows 10 apps called RelativePanel. It's really easy to use, although as XAML developers, we're used to thinking about layout based on Grids and StackPanels and similar panels. RelativePanel requires a slightly different way of thinking about layout, but it simplifies adaptability and can really help in reducing XAML both to describe layout and to define different VisualStates. However, there are some dangers and scenarios to keep in mind when defining the layout using RelativePanel and it will take some time for developers to get used to it.
Note that that everything here is written using Windows 10 Technical Preview build 10061 and Technical Preview Tools, so things can change.
RelativePanel is really easy to understand and implement. Let's say we wanted to have 2 rectangles in the UI where the red one is on top, and the blue rectangle is below the red rectangle, but right-aligned with the red rectangle.
This is how you would define this in XAML using RelativePanel:
<RelativePanel> <Rectangle x:Name="Red" Height="100" Width="200" Fill="Red"/> <Rectangle x:Name="Blue" Height="100" Width="100" Fill="Blue" RelativePanel.Below="Red" RelativePanel.AlignRightWith="Red"/> </RelativePanel>
As simple as that.
However, things may get more complicated than this (and they will as soon as you start developing your app), and there are 3 dangers that you need to be cautious about.
Item moved off the screen
What happens in case the blue rectangle stayed below the red rectangle, but was set to be left of the red rectangle, like this:
<RelativePanel> <Rectangle x:Name="Red" Height="100" Width="200" Fill="Red"/> <Rectangle x:Name="Blue" Height="100" Width="100" Fill="Blue" RelativePanel.Below="Red" RelativePanel.LeftOf="Red"/> </RelativePanel>
All of a sudden, the blue rectangle is not visible anymore. Why? Because the default position of any child in the RelativePanel is TOP-LEFT (horizontally aligned to the left, vertically aligned to the top of the panel), putting anything to the left of what's already aligned left with the panel will result with invisible element. It's there, just went out the window. :)
There is nothing in the XAML designer to warn you about this, so you have to be careful.
What happens if you want to have a blue rectangle horizontally and vertically centered, and then the red rectangle horizontally centered with the blue rectangle, but at the same time left of the red rectangle?
Let's show this scenario in code:
<RelativePanel> <Rectangle x:Name="Red" Height="100" Width="200" Fill="Red" RelativePanel.AlignHorizontalCenterWith="Blue" RelativePanel.LeftOf="Blue"/> <Rectangle x:Name="Blue" Height="100" Width="100" Fill="Blue" RelativePanel.AlignHorizontalCenterWithPanel="True" RelativePanel.AlignVerticalCenterWithPanel="True"/> </RelativePanel>
What do you think will happen?
Here's the result:
LeftOf is completely ignored, and the red rectangle is horizontally centered above the blue rectangle.
Again, nothing that the designer or runtime will tell you about - you'll have to be careful.
When a conflict happens, the relationships are applied in the following order of priority:
- Panel alignment relationships (AlignTopWithPanel, AlignLeftWithPanel ...) are applied first.
- Sibling alignment relationships (AlignTopWith, AlignLeftWith ...) are applied second.
- Sibling positional relationships (Above, Below, RightOf, LeftOf) are applied last.
The panel-center alignment properties (AlignVerticalCenterWith, AlignHorizontalCenterWithPanel ...) are typically used independently of other constraints and are applied if there is no conflict. (source: https://msdn.microsoft.com/library/windows/apps/windows.ui.xaml.controls.relativepanel.aspx)
What if you defined that the red rectangle is above the blue rectangle, and the blue rectangle is below the red rectangle? It may sound reasonable to you, after all if one item is above another, it's only logical that the second item is below the first one. But that doesn't work that way when rendering items.
Check out this simple scenario in code:
<RelativePanel> <Rectangle x:Name="Red" Height="100" Width="200" Fill="Red" RelativePanel.Above="Blue"/> <Rectangle x:Name="Blue" Height="100" Width="100" Fill="Blue" RelativePanel.Below="Red"/> </RelativePanel>
In this case you will get an exception so it will be pretty clear what's going on.
RelativePanel error: Circular dependency detected. Layout could not complete."
RelativePanel is a great new panel that will help us simplify XAML and more easily implement adaptive UI. However, until we're all used to using it, there are a few things to keep in mind!
Have you tried RelativePanel? How did you like it? Leave a comment!