3
votes

I am new to Windows Runtime programming and decided to get stuck in ahead of the release of Windows 10.

I am trying to design an adaptive page UI that looks something like as follows, Desktop view There is header "stuff" at the top and beneath it I want two columns, each with a textblock header and below it, a listview. The listview could be arbitraryheight and so the parent of the two blocks should, I think, be a scrollviewer.

On mobile however, this UI won't work as the screen is far to narrow, and so I would like to use a visualstate to rearrange the page so it looks as follows, Mobile view

As you can see, the need for a scrollviewer is apparent to wrap this section. the "Other stuff" at the top should stay fixed however so it can be seen all the time.

I have tried a number of approaches to achieve this but haven't been able to manage it. What I currently have is this:

//.... Other Stuff ......
<ScrollViewer x:Name="SummaryScrollViewer" Grid.Row="2" HorizontalScrollBarVisibility="Disabled"
              HorizontalScrollMode="Disabled" VerticalScrollMode="Auto" VerticalScrollBarVisibility="Auto" HorizontalContentAlignment="Center">
        <RelativePanel x:Name="SummaryRelativePanel">
            <Grid x:Name="lCol" Width="{Binding ActualWidth, ElementName=SummaryRelativePanel}">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <TextBlock x:Name="lcolHead" Grid.Row="0" Text="TextBlock:"/>
                <ListView x:Name="lcolList" Grid.Row="1">
                </ListView>
            </Grid>
            <StackPanel x:Name="rCol" Orientation="Vertical" RelativePanel.RightOf="lCol">
                <TextBlock x:Name="rcolHead" Text="TextBlock:"/>
                <ListView x:Name="rcolList" Height="Auto">
                </ListView>
            </StackPanel>
        </RelativePanel>
    </ScrollViewer>

As you can see, I have tried to make the contents of each column both a stackpanel, and a grid, but I haven't been able to set the width of them to be, in "desktop view", half that of the containing relative panel, which should fill the full width of the screen, and in "mobile view" they should fill the full width of the parent.

I have found answers on how to bind the width to the ActualWidth property of the parent element as can be seen in the snippet, and this works, but I can't seem to make the two columns fill half of the parent each.

I wanted to use a RelativePanel so I can use the viewstate to change the properties of the right hand column to be either RightOf="LeftCol" or Below="LeftCol", and the widths should then be updated too to fill the width required.

Using a grid Should also be possible, define a 4x4 grid where in desktop the bottom two are collapse, or in mobile the right two are collapsed, but I was under the impression that this is the precise usecase the relativepanel was intended for.

In all examples of relativepanel they use relativepanel to move programmer defined with/height elements such as rectangles RelativePanel class.

It would also be possible to manually set ActualWidth of each column programatically from the code-behind but I don't know how to query which visual state the app/page is currently in to figure out how wide and where each column should be.

Any help and advice on what the "best" way to achieve such a thing would be would be greatly appreciated.

1

1 Answers

2
votes

Here we go, let's begin that the bugs (or things I think are bugs)

1.- If I set a control with binding to the RelativePanel ActualWidth it just takes the first time, I mean, if I expand the window the control does not resize, so bug?

So let's do it with Grid:

<Grid x:Name="LayoutRoot" Background="Red" >

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="WindowSizeStates"  >
        <VisualState x:Name="SmallScreen"  >
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="0"/>
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Target="ContentLayoutRoot.Background" Value="Green"/>
                <Setter Target="ContentLayoutRoot.RowDefinitions[0].Height" Value="100"/>
                <Setter Target="ContentLayoutRoot.RowDefinitions[1].Height" Value="400"/>
                <Setter Target="ContentLayoutRoot.RowDefinitions[2].Height" Value="100"/>
                <Setter Target="ContentLayoutRoot.RowDefinitions[3].Height" Value="400"/>

                <Setter Target="ContentLayoutRoot.ColumnDefinitions[0].Width" Value="1*"/>
                <Setter Target="ContentLayoutRoot.ColumnDefinitions[1].Width" Value="0"/>

                <Setter Target="SubHeaderOneLayout.(Grid.Row)" Value="0"/>
                <Setter Target="ContentOneLayout.(Grid.Row)" Value="1"/>
                <Setter Target="SubHeaderTwoLayout.(Grid.Row)" Value="2"/>
                <Setter Target="ContentTwoLayout.(Grid.Row)" Value="3"/>

                <Setter Target="SubHeaderTwoLayout.(Grid.Column)" Value="0"/>
                <Setter Target="ContentTwoLayout.(Grid.Column)" Value="0"/>
            </VisualState.Setters>
        </VisualState>

        <VisualState x:Name="WideScreen">
            <VisualState.StateTriggers>

                <AdaptiveTrigger MinWindowWidth="1000" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Target="ContentLayoutRoot.Background" Value="Purple"/>
                <Setter Target="ContentLayoutRoot.RowDefinitions[0].Height" Value="100"/>
                <Setter Target="ContentLayoutRoot.RowDefinitions[1].Height" Value="900"/>
                <Setter Target="ContentLayoutRoot.RowDefinitions[2].Height" Value="0"/>
                <Setter Target="ContentLayoutRoot.RowDefinitions[3].Height" Value="0"/>

                <Setter Target="ContentLayoutRoot.ColumnDefinitions[0].Width" Value="0.5*"/>
                <Setter Target="ContentLayoutRoot.ColumnDefinitions[1].Width" Value="0.5*"/>

                <Setter Target="SubHeaderOneLayout.(Grid.Row)" Value="0"/>
                <Setter Target="ContentOneLayout.(Grid.Row)" Value="1"/>
                <Setter Target="SubHeaderTwoLayout.(Grid.Row)" Value="0"/>
                <Setter Target="ContentTwoLayout.(Grid.Row)" Value="1"/>

                <Setter Target="SubHeaderTwoLayout.(Grid.Column)" Value="1"/>
                <Setter Target="ContentTwoLayout.(Grid.Column)" Value="1"/>

            </VisualState.Setters>
        </VisualState>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

<Grid.RowDefinitions>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="1*"/>
</Grid.RowDefinitions>

<Grid x:Name="HeaderLayout"  VerticalAlignment="Top" Height="32"> 
    <TextBlock Text="Other Stuff" HorizontalAlignment="Center"/>
</Grid>

<ScrollViewer Grid.Row="1">
<Grid  x:Name="ContentLayoutRoot">

    <Grid.RowDefinitions>
        <RowDefinition Height="100"/>
        <RowDefinition Height="900"/>
        <RowDefinition Height="0"/>
        <RowDefinition Height="0"/>
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="0.5*"/>
        <ColumnDefinition Width="0.5*"/>
    </Grid.ColumnDefinitions>

    <Grid x:Name="SubHeaderOneLayout"  >
        <TextBlock Text="Sub Header One" HorizontalAlignment="Center"/>
    </Grid>

    <Grid x:Name="SubHeaderTwoLayout"  Grid.Column="1">
        <TextBlock Text="Sub Header Two" HorizontalAlignment="Center"/>
    </Grid>

    <Grid x:Name="ContentOneLayout" Background="Orange"  Grid.Row="1">
        <TextBlock Text="ContentOne Layout" HorizontalAlignment="Center"/>
    </Grid>

    <Grid x:Name="ContentTwoLayout" Background="Orange"  Grid.Row="1" Grid.Column="1">
        <TextBlock Text="ContentOne Layout" HorizontalAlignment="Center"/>
    </Grid>

</Grid>
</ScrollViewer>

I could try to make it with Relative Panel but involves events, and more things, tell me if it is enough. And, well the triggers I discovered by myself, you can get more info in my article in codeproject