When Lists aren’t Vertical or Horizontal – Going Diagonal with Windows ListView Control

The designer for a project we’re currently working on just pitched an idea where there would be a list of items that were presented along a diagonal. Back in Silverlight this probably would have been accomplished using a PathListBox but of course that doesn’t exist in the Windows 8 world. So this got me thinking …. and actually I had to reach out to UX guru Shane Morris for some inspiration. Whilst I’m not using the viewbox suggestion he had, the solution was much easier than I initially thought and essential revolves around rotating the ListView one direction and the items in the list back the other way (so they’re still horizontal).

My first pass was literally just that. A rotate transform of 27 degrees on the ListView and then a –27 degree rotate on the first item in the ItemTemplate:

<ListView>
    <ListView.RenderTransform>
        <CompositeTransform
            Rotation="27" />
    </ListView.RenderTransform>
</ListView>

<DataTemplate
    x_Key="MyItemTemplate">
    <Grid
        RenderTransformOrigin="0.5,0.5">
        <Grid.RenderTransform>
            <CompositeTransform
                Rotation="-27" />
        </Grid.RenderTransform>
        <!–     …. –>
    </Grid>
</DataTemplate>

Unfortunately this didn’t work particularly well as it ended up with too many layout issues (see below image). There was incorrect header/footer spacing but more importantly the hover effect (ie the grey background) wasn’t being rotated.

image

My next attempt involved still rotating the ListView but instead of rotating a child of the ItemTemplate I instead rotated the ListViewItemPresenter which is found by right-clicking on the ListView and selecting Edit Additional Templates, Edit Generated Item Container (ItemContainerStyle), Edit a Copy (first time only).

image

<ListViewItemPresenter …. RenderTransformOrigin="0.5,0.5">
    <ListViewItemPresenter.RenderTransform>
        <CompositeTransform Rotation="-27"/>
    </ListViewItemPresenter.RenderTransform>
</ListViewItemPresenter>

Now we’re getting closer – the hover aligns with the item as they’re both being correctly rotated. I still had issues with the positioning on the screen to ensure items scroll all the way to the edge of the screen and that all of them can still be scrolled completely into view. Firstly, I had to adjust the position of the ListView so that after rotating the trailing corner is flush with the top and bottom of the screen.

image

Doing this will prevent the first and last item being able to be scrolled into view. This can be fixed by adding a spacer into the header and footer template of the ListView.

The last issue to overcome is that the scroll bar goes off the screen at the bottom.

image

This can be fixed by tweaking the template of the scrollviewer, setting a bottom margin to lift the vertical scrollbar back onto the screen. To get to this template you have to edit the template of the ListView (not one of the additional templates), then edit the template of the ScrollViewer (which itself is part of the ListView template).

The result is that we have items that are presented, and scroll, along a diagonal line.

image

Leave a comment