February 2016

Volume 31 Number 2

[Windows 10]

Universal Windows Platform Apps for Web Developers

By Tim Kulp | February 2016

As an enterprise Web developer, you have a keen understanding of HTML, CSS and JavaScript. You can build out responsive Web applications that adapt to the screen size while maintaining functionality across your supported browsers or devices. The same skills you use to light up the Web can be used to build Universal Windows Platform (UWP) apps. Whether you’re building for desktop, mobile or any Windows 10 platform, your lessons learned from cross-browser adaptive Web applications will give you a head start in UWP.

In this article, I explore how to use knowledge from Web development to go from building cross-browser applications to flexible UWP apps that run on any Windows device. To do this, I start by examining how the fundamentals of building responsive inter­faces translate from CSS and HTML to UWP. Next, I examine using VisualStates and XAML Views to structure your app based on specific device capabilities. Finally, I use Adaptive Code to target devices based on how Plain Old JavaScript is used to target specific browsers.

Why XAML for Web Developers?

In this article, I’ll build parallels from Web development to XAML. Web developers might already have a strong HTML/CSS/JavaScript skillset and want to build UWP with that skillset. If you love HTML and JavaScript, feel free to stick with it. If you’re new to UWP and unsure where to start, XAML is a great tool to help you due to its strongly typed nature.

A common example of this is using a grid-based layout in XAML versus HTML. In XAML, building a grid layout starts with adding a grid control, defining the columns and rows, then assigning each control within the grid to a specific cell or row. In HTML, there are numerous ways to build a grid layout such as:

  • Using floats with defined height and width to create cells with clears to start a new row
  • Using display:grid on the container element with each child element having a column and row defined
  • Using a table with tr and td elements

Which is implemented is up to your knowledge of CSS or HTML and these approaches won’t give you help through tools such as IntelliSense, as the grid control will in XAML. The strongly typed controls of XAML make it easier to know how to build a UI through IntelliSense, which is extremely helpful for developers who are new to UWP.

Strongly typed code also provides a lot of value when troubleshooting issues. In HTML/CSS/JavaScript, developers have great flexibility to bend the rules to the demands of the app using loosely typed code. This is great for building apps but can be a nightmare for supporting apps. Troubleshooting loosely typed code can be a challenge when types change or objects change dynamically. As enterprise developers, building apps is fun, but at some point, someone is going to have to keep this app running. The ability to easily navigate the functionality of an app through strongly typed objects and IntelliSense helps the support team understand the app.

If you’re passionate about HTML/CSS/JavaScript, UWP gives you a platform to use your existing code to produce great apps. HTML/CSS/JavaScript and XAML are both great tools with lots of pros and cons. There are two articles about why one author prefers XAML to JavaScript (bit.ly/1NxUxqh) and another prefers JavaScript to XAML (bit.ly/1RSLZ2G). I love HTML for Web applications but I encourage you to explore XAML if you’re new to UWP to learn the controls within UWP, to keep support costs down for your team through strongly typed code with rich IntelliSense integration and to have fun learning something new.

Building on What You Already Know

UWP has many similarities with the fundamentals of Web design. Basic ideas such as separation of concerns in Web development between HTML and JavaScript translate in UWP to XAML and the XAML.cs codebehind file. All logic goes into the codebehind, while all presentation is maintained in the XAML file (just as all logic goes in JavaScript while presentation is in HTML with help from CSS). Further, many modern Web applications leverage frameworks such as Knockout and AngularJS to implement data binding through the Model-View-ViewModel (MVVM) design pattern. Knowledge of these frameworks and MVVM in general is the basis for understanding data binding in UWP. While the syntax is different between Web development and UWP, when it comes to basic concepts, Web developers have a strong foundation for building apps that cross devices, browsers and capabilities.

There are differences between Web development and UWP that I won’t cover in this article, such as state management and data storage. For this article, I’ll focus on building the UI and ensuring that the app can interact with the device on which it’s running.

Positioning: Float and Clear to RelativePanel

In HTML, you determine the positioning of each element by where it is in the Document Object Model. HTML is top-down with each element being rendered in order from the first element declared to the last. When CSS was introduced, it let elements have sophisticated layouts based on setting the element’s display style (inline, block and so on), position (relative or absolute), as well as float and clear. Using float, Web developers could take an HTML element out of the top-down flow, and place the element to the left (float: left) or right (float: right) of the containing element.

Imagine a simple layout including header, main content, sidebar and footer. Using float instructs the browser to render the sidebar to the right edge of the container and to render the main content to the left edge of the container. Using float, elements will position beside each other to the left or right, depending on which float value is specified. Clear is used to stop the floating of elements and return to the standard top-down flow of HTML. Figure 1 shows an example of using float to build a simple layout.

Figure 1 Using Float to Build a Simple Layout

div {
  width: 100%;
}
mainContent {
  width: 60%; float: left;
}
  sidebar{
  width: 40%; float: right;
}
clearer {
  clear: both;
}
CSS for design
<header>
</header>
<div>
  <section class="content"></section>
  <section class="sidebar"></section>
  <div class="clearer"></div>
</div>
<footer>
</footer>
HTML for design

Where Web developers use float and clear to create a layout, UWP provides a control called the RelativePanel, which, as the name suggests, lets a layout be defined using relative relationships to other controls. Like float, RelativePanels let developers manage how controls are positioned relative to an anchor control. CSS classes are used to determine positioning of the elements of the Web page. To replicate the same layout, use the RelativePanel and the RelativePanel’s attached properties within the controls:

<RelativePanel>
  <!-- Header is the anchor object for the relative panel -->
  <TextBlock Text="Header" Name="tbHeader"></TextBlock>
  <TextBlock Text="Content" RelativePanel.Below="tbHeader"
    Name="tbContent"></TextBlock>
  <TextBlock Text="SideBar" RelativePanel.RightOf="tbContent"
    RelativePanel.Below="tbHeader" Name="tbSideBar"></TextBlock>
  <TextBlock Text="Footer" RelativePanel.Below="tbSideBar"
    Name="tbFooter"></TextBlock>
</RelativePanel>

In this code block, the positioning of each control is relative to the position of the anchor control (in this case, the anchor is the header TextBlock). Using RelativePanel, each control can be assigned to where the control should appear on the screen in relation to the other controls. Where Web developers would use float: left, UWP developers would use RelativePanel.LeftOf or Relative­Panel.RightOf (for float: right) to position content. While this is similar to using float, there isn’t a concept of using clear to return to the normal flow; instead, just note that something is below a previous element. This simplifies troubleshooting layout issues as managing floats and clears can get challenging for developers who do not have strong CSS skills. Using the RelativePanel provides a declarative way to specify where a control should appear in relation to other controls. When the RelativePanel is closed, the app will return to the normal rendering flow of XAML (which is top-down like HTML).

Scaling: Percentages to Pixels

Building a responsive Web application through resizing means using relative sizing for elements. Using the header, content, sidebar and footer page layout, imagine this UI was originally built for a desktop screen. Web designers would first identify the optimal pixel width for the page for this layout. In this example, page width will be 1000px. As each element is built in the design, the element is built to the pixel width keeping the 1000px container in mind. In HTML, the content section would be 800px wide while the sidebar section would be 200px wide. Using the formula: target / context = percentage, the content section is 80 percent of the context (whereas the context = the 1000px page) while the sidebar is 20 percent.

Using percentages in Web design lets the layout resize as the container resizes. In this case, if the 1000px page object were resized by the user to only 659px, the content and sidebar would resize to 527px and 131px, respectively. Similarly, building styles to use em instead of specific point or pixel sizes lets the font scale according to the context. These practices help ensure that a design maintains the proportional sizing independent of the window size.

While using percentages seems like simple math, there are other factors that are involved in how elements scale, such as pixel density of the device and orientation, which add an element of unpredictability to your design. UWP simplifies scaling by using the concept of the “effective pixel” for all measurements. An effective pixel is not the same as a single pixel. Effective pixels use the UWP scaling algorithm to know how to represent one effective pixel based on standard distance of the device from the user and pixel density.

As an example, a Surface Hub would have a much higher pixel density than a tablet or phone. UWP developers only need to build to effective pixels in tools such as Blend and let the scaling algorithm handle the complex calculations necessary to shrink or grow accordingly. One thing to keep in mind: Effective pixels must be in multiples of four. Based on how the scaling algorithm works, using multiples of four will ensure clean edges as the UI scales.

ViewStates and Media Queries

In Web development, CSS provides the layout information for an application. Building with percentages lets an application resize, but at some point, the design needs to break and reform to meet the changing display demands. A layout built for a mobile device such as a tablet isn’t going to be the same as a layout built for an 80-inch-plus presentation device such as the Surface Hub. An older analogy for Web design is the case where a user would want to print a screen-based design. CSS let designers fix the screen-to-print dilemma with CSS media queries. As the user printed the design, the browser would use the print CSS instead of the screen CSS. As responsive Web design has grown, media queries have grown to support information that is more detailed. Here’s an example CSS media query:

<link type="text/css" rel="stylesheet" 
  href="styles/719style.css"
  media="screen and (max-device-width: 719px)"/>

In this query, the 719style.css file is applied if the media displaying the Web application is a screen with a device width less than or equal to 719px. As an example, this media query can be used to clear the float values and present the content and sidebar elements in a stacked design versus side-by-side. Using media queries lets Web developers customize the display based on screen size, resolution, orientation and many more options (see complete list for CSS3 at bit.ly/1riUA2h).

In UWP, the ViewStateManager can be used as media queries to alter the application design based on defined parameters. The VisualStateManager contains one or more VisualStateGroups, a container object of multiple ViewStates. Each ViewState holds the setters (what properties get updated for each control) and triggers (what makes the setters change). ViewStateManager manages the triggers to know when to apply a specific ViewState’s setter values. In the terms of CSS, the triggers are like media queries and the setters are the style values within the stylesheet referenced in the media query. See the example in Figure 2.

Figure 2 Reposition Controls Based on VisualState Triggers

<VisualStateManager.VisualStateGroups>
  <VisualStateGroup x:Name="ResponseStateGroup">
    <VisualState x:Name="LessThan720">
      <VisualState.Setters>
      <Setter Target="tbSideBar.(RelativePanel.Below)" Value="tbContent"/>
        <Setter Target="tbSideBar.(RelativePanel.RightOf)" Value=""/>
      </VisualState.Setters>
      <VisualState.StateTriggers>
        <AdaptiveTrigger MinWindowWidth="1"/>
      </VisualState.StateTriggers>
    </VisualState>
    <VisualState x:Name="GreaterThan720">
      <VisualState.Setters>
        <Setter Target="tbSideBar.(RelativePanel.Below)" Value="tbHeader"/>
        <Setter Target=" tbSideBar.(RelativePanel.RightOf)" Value="tbContent"/>
      </VisualState.Setters>
      <VisualState.StateTriggers>
        <AdaptiveTrigger MinWindowWidth="720"/>
      </VisualState.StateTriggers>
    </VisualState>
  </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

In this code, two VisualStates are set up. The LessThan720 ViewState is triggered when the window width is 1px to 719px. When the window expands to 720px or higher, then the GreaterThan720 ViewState is triggered. Each of these ViewStates work with the tbSideBar control’s RelativePanel settings. If the window size is less than 720, then the screen isn’t big enough to support a design where content is beside the sidebar. In this situation, the LessThan720 ViewState will be triggered, which will stack the sidebar below the main content TextBlock. This is similar to using the media query in that I can set float: none in a LessThan719.css file.

Just like media queries, ViewStates can be used to reposition or rearchitect controls based on the triggers. Managing ViewStates and ViewStateGroups can get complicated as an interface grows in complexity. Managing complex ViewState changes are easiest with Blend for Visual Studio 2015. Using Blend’s editor, you can create new VisualStates and see the changes in the app design as you make them. Blend will handle writing all the XAML for you and ensure that you provide the necessary data to trigger the VisualState change. Microsoft Virtual Academy has great walk-through videos on using Blend for ViewState management at bit.ly/1P94e32.

Using Views to Rearchitect the Experience

Sometimes a mobile site is a different UI due to a reduction in use cases or change in focus that the mobile site provides versus the full desktop experience. In this scenario, Web developers would tailor content to the mobile experience for a more streamlined experience, or to highlight the capabilities of the mobile device. Using various detection methods, Web developers can redirect users to a rearchitected experience tailored to their device, often known as the m.webapp.com site.

UWP provides the same capability through Views. Depending on the app, working with different device families might call for such a stark difference in UI for which the ViewStateManager might not be the right tool. Views let developers leverage the existing back-end code with a new XAML UI. You can simplify Using Views through using well-structured ViewModels whereas you can leverage a single ViewModel object by multiple Views. Knowledge of Knockout or AngularJS will help Web developers build proper ViewModels in UWP for tailored UXes for a specific device family.

You set up a View for a specific device by creating a folder within the app’s Views folder.

Within the Views folder, create a new folder called Device­Family-Mobile. This tells the Modern Resource Technology to use the MainPage.xaml view found in the DeviceFamily-Mobile folder when the MainPage is requested on a device in the mobile device family (such as a phone). If the request for MainPage comes from any other device family, the response will be the standard MainPage. This functionality lets UWP developers build targeted UI for use cases that are unique to specific Windows device families.

Adaptive Code

In building Web applications, not all browsers are the same. In an enterprise, you might have a corporate standard, but when developing for external users, complexity comes from various OSes, browser types and versions. Web developers have many tricks up their sleeves to handle these differences gracefully. Libraries such as Modernizr (modernizr.com) have made handling these complexities easier, but enabling features based on device or browser is nothing new to Web developers.

Building UWP apps can have the same complexities as cross-browser functionality. Imagine a note-taking application where users can add pictures to their notes. The app could leverage the built-in camera functionality of a phone to take a picture, or could just let users view images that already exist on their devices.

The first step in using device-specific capabilities is ensuring the proper Extension APIs are included in the project. As an example, in the note-taking app, the hardware buttons would need to be accessible on a phone. To use those buttons, you must add a reference to the Windows Mobile Extensions for the UWP. This is done by adding a reference to the project (just like any other reference), then selecting Universal Windows, then Extensions. You will see a list of possible extensions such as Desktop, Mobile and Team (for Surface Hub) extensions. Select which extensions you need to add to the project and click OK.

Wherein JavaScript detecting the browser’s capabilities would be through a series of navigator checks, in UWP the app checks for the presence of the needed API through the IsTypePresent method. In the note-taking app, check for the hardware button to use the camera through the following code:

string apiName = "Windows.Phone.UI.Input.HardwareButtons";
if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent(apiName))
{
  Windows.Phone.UI.Input.HardwareButtons.CameraPressed +=
    HardwareButtons_CameraPressed;
}

This short code lets the app target specific device capabilities added through the Extension APIs. By wrapping the CameraPressed event handler declaration with the IsTypePresent method, you ensure that you don’t try to register the event handler when the API isn’t present. There are tools to help ensure that the API checks occur so that the app doesn’t crash when the API isn’t present. PlatformSpecific is an excellent NuGet package that simplifies identifying and wrapping any reference to an extension API that isn’t first validated through the ApiInformation.IsTypePresent method. Learn more about this NuGet package from the PlatformSpecific GitHub site at bit.ly/1GvhkF0.

Just as in Web development, sometimes a specific version of the browser needs targeting for a client or corporate standard. In these situations, Web developers need to focus on a specific browser configuration that might not match what the rest of the Internet is using.

Similarly, UWP developers might need to target specific contracts of an extension API to maintain existing code. This is very useful in enterprise applications where the IT operations team could have a fast loop and slow loop for deploying updates to employee computers. The fast loop might be getting a new great feature of some extension API that must be implemented in the app immediately. In this situation, the slow loop users still need their functionality. Using IsApiContractPresent UWP can check that the extension API is available and that the specific version expected is available prior to executing the code:

if(Windows.Foundation.Metadata.ApiInformation.IsApiContractPresent(apiName, 3))
{
  newKillerFunction();
}

In this code segment, the app will only run the newKillerFunction if the apiName provided is at version 3. If the version is less than 3, then newKillerFunction will not run. If a greater version is present (as example, version 4), then newKillerFunction will execute.

Wrapping Up

UWP development leverages many of the skills and knowledge that Web developers use to build responsive, cross-browser Web applications. Designing layout, responding to differences in displays (both static and dynamic), as well as system capabilities, are all common practices to Web developers from dealing with the wild world of Web browsers. Applying these skills in UWP development will help in building rich UXes that adapt to screen size, device and capabilities.


Tim Kulp is a senior technical architect living in Baltimore, Md. He is a Web, mobile and UWP developer, as well as author, painter, dad and “wannabe Mad Scientist Maker.” Find him on Twitter: @seccode or via LinkedIn: linkedin.com/in/timkulp.

Thanks to the following Microsoft technical expert for reviewing this article: Kevin Hill