Search code examples
xamlresponsive-designwin-universal-appwindows-10windows-10-mobile

How do I create a design breakpoint in Windows 10 XAML?


The Responsive Design Guide for Windows 10 apps talks about responsive design techniques and in particular about using design breakpoints for specific size classes:

Design breakpoints for specific size classes

The number of device targets and screen sizes across the Windows 10 ecosystem is too great to worry about optimizing your UI for each one. Instead, we recommended designing for a few key widths (also called "breakpoints"): 320, 720, and 1024 epx.

See: https://msdn.microsoft.com/en-us/library/windows/apps/dn958435.aspx#sizeclasses

The article describes the general concept of responsive design and design breakpoints. I'm already familiar with these concepts from HTML and CSS media queries. But I don't know how to do it in XAML?

Searching for Windows 10 and design breakpoints doesn't yield the information I want, can you point me in the right direction?


Solution

  • Design breakpoints for specific size classes is just a concept, a recommendation to give you key sizes to worry about. As Justin mentioned, one really simple way to accomplish that is to use visual state triggers to trigger changes in your UI based on minimum window width. There is a state trigger called AdaptiveTrigger that allows you to do that out of the box. There are other available open source state triggers, but the AdaptiveTrigger is the one you need to react to different widths, or breakpoints, in XAML. Here's a very simple example:

    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="AdaptiveSizesVisualStateGroup">
            <VisualState x:Name="Large">
                <!-- VisualState to be triggered when window width is >=1024 effective pixels -->
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="1024" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="MySplitView.IsPaneOpen" Value="True" />
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="Medium">
                <!-- VisualState to be triggered when window width is >=720 and < 1024 effective pixels -->
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="720" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="MySplitView.IsPaneOpen" Value="False" />
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="Small">
                <!-- VisualState to be triggered when window width is >=320 and < 720 effective pixels -->
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="320" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="MySplitView.IsPaneOpen" Value="False" />
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="Minimum">
                <!-- VisualState to be triggered when window width is >=0 and < 320 effective pixels -->
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="0" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="MySplitView.IsPaneOpen" Value="False" />
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    

    You can see that I used a different visual state for different window width. AdaptiveTrigger is the object taking care of actually noticing that the window size has changed and triggering a particular visual state inside a visual state group. Once a visual state is active, the setters are used to set different values to different target objects in XAML. In my code example, I am keeping the SplitView pane closed for all the widths except when >= 1024 effective pixels.

    Now, even though AdaptiveTriggers are easy to use, it's very easy to clutter your XAML code with a bunch of setters in each visual state, and it may be hard to maintain that code. Just look how much XAML I wrote for a dummy sample! Also, it's possible that you will want major differences in the UI between Phone and Desktop, so your best bet could end up being writing specific XAML Views tailored for specific device families, which could also have AdaptiveTriggers inside...