Search code examples
xamlwindows-10win-universal-appwindows-10-mobile

Windows Universal responsive design reposition


So, I've just started working again with Windows apps and there are a few things that I can't get working as I want (probably because I coulnd't find any sample and Channel9 videos didn't cover my case).

Starting from this article, I decided that the "reposition" technique is the one that fits my app when moving from a big screen to a smaller one.

What I did is using a StackPanel and changing its orientation using two AdaptiveTriggers (one for 0 width and another one for 720, based on the table here).

This kinda works but there are some issues that I'll illustrate with some ugly paint-edited screenshots.

This is what happens when I'm in the BigScreen situation, where there's enough space to have both A and B on the same row. The problem here is that B should take the full remaining width, covering all the blue part.

BigScreen

The second issue is related to resizing. When there's not enough space, the green part gets cut instead of being resized (you can see that the right border disappeared). This didn't happen before using the StackPanel to make the layout responsive.

HalfScreen

Finally, when we are in the SmallScreen situation, orientation changes to be vertical and we have the same problem as the first one: green part's height doesn't fill the screen.

SmallScreen

Here's the XAML used for the page:

<Page
    x:Class="Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:WifiAnalyzerFinal.Views"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:mvvm="using:Mvvm"
    mc:Ignorable="d">        

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="SmallScreen">
            <VisualState>
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="0"/>
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="StackPanel.Orientation" 
                            Value="Vertical"/>
                </VisualState.Setters>
            </VisualState>
            </VisualStateGroup>
            <VisualStateGroup x:Name="BigScreen">
            <VisualState>
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="720"/>
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="StackPanel.Orientation" 
                            Value="Horizontal"/>
                    <Setter Target="Rect.Width" 
                            Value="200"/>
                        <Setter Target="Rect.Height" 
                            Value="Auto"/>
                    </VisualState.Setters>
            </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <StackPanel Orientation="Vertical"
                    Background="Blue"
                    x:Name="StackPanel">
            <Rectangle Fill="Red" 
                       Height="50"
                       x:Name="Rect"
                       Width="Auto"/>
            <ListView ItemsSource="{Binding Stuff}"
                      HorizontalAlignment="Stretch"
                      HorizontalContentAlignment="Stretch"
                      VerticalAlignment="Stretch"
                      Background="Green"
                      Width="Auto"
                      BorderBrush="DarkGreen"
                      BorderThickness="5"
                      Padding="5">
                <ListView.ItemContainerStyle>
                    <Style TargetType="ListViewItem">
                        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                        <Setter Property="Margin" Value="0,0,0,5"/>
                    </Style>
                </ListView.ItemContainerStyle>
            </ListView>
        </StackPanel>
    </Grid>
</Page>

Please note that without the StackPanel the green part fits the page as it should, covering all the available area. Unfortunately I couldn't came up with a better solution because there's no sample telling us how this technique should be implemented. I also tried using the new RelativePanel but it seems that the AdaptiveTrigger's Setter doesn't work with attached properties like RelativePanel.RightOf.

Is there someone who's been successful is applying this technique without having to use code-behind?

EDIT:

I got this working using a Grid with 2 rows and 2 columns, with the AdaptiveTrigger moving all the content from row to column and viceversa.


Solution

  • It is possible to change RelativePanel attached property values through setters. The syntax goes like this:

    <Setter Target="SomeXAMLObject.(RelativePanel.RightOf)" Value="SomeOtherXAMLObject" />