{"id":6143,"date":"2015-06-17T12:00:17","date_gmt":"2015-06-17T10:00:17","guid":{"rendered":"http:\/\/www.centigrade.de\/blog\/?p=6143"},"modified":"2020-01-25T19:39:41","modified_gmt":"2020-01-25T18:39:41","slug":"contextual-user-interface-design-engineering-with-the-universal-windows-platform","status":"publish","type":"blog","link":"https:\/\/www.centigrade.de\/en\/blog\/contextual-user-interface-design-engineering-with-the-universal-windows-platform\/","title":{"rendered":"Contextual User Interface Design Engineering with the Universal Windows Platform"},"content":{"rendered":"<p>Recently I gave a talk at the <a title=\"Website dotnet Cologne\" href=\"http:\/\/dotnet-cologne.de\/\" target=\"_blank\" rel=\"noopener noreferrer\">dotnet Cologne<\/a>\u00a0and also at the <a href=\"http:\/\/www.developer-week.de\/\" target=\"_blank\" rel=\"noopener noreferrer\">DWX \u00a0Developer Week<\/a> titled &#8220;4K and other challenges \u2013 Next Generation Desktop UIs for Windows 10&#8221;. The session discussed the term Universal App Platform in Windows 10 and showed what a developer can make out of it in order to create future oriented user interfaces. This blog article is not only supposed to target those who attended my session, but also those who were not present to hear it. Moreover the article will provide further information to the topic. As in the session there will be a coding part at the end where some new Universal App features are shown.<!--more--><\/p>\n<h3>Retrospection of Windows 8<\/h3>\n<div id=\"attachment_6036\" style=\"width: 680px\" class=\"wp-caption alignnone\"><img decoding=\"async\" aria-describedby=\"caption-attachment-6036\" src=\"https:\/\/www.centigrade.de\/wordpress\/wp-content\/uploads\/Windows8-SampleScreen.jpg\" alt=\"Windows 8 Start screen\" width=\"670\" \/><p id=\"caption-attachment-6036\" class=\"wp-caption-text\">Windows 8 Start screen (Reference: <a title=\"MS News Center (Windows 8)\" href=\"http:\/\/news.microsoft.com\/?attachment_id=24896\" target=\"_blank\" rel=\"noopener noreferrer\">Microsoft News Center<\/a>)<\/p><\/div>\n<p><em>One UI to rule them all<\/em> may have been the first impression Windows 8 made to most of its users back in 2012. The touch oriented, flashy tile interface and the missing start menu seemed to be a major break in consistency for many users. However there was a lot going on behind the scenes. In accordance to the <a title=\"Platform Convergence Journey in MVA Video\" href=\"http:\/\/www.microsoftvirtualacademy.com\/training-courses\/a-developers-guide-to-windows-10\" target=\"_blank\" rel=\"noopener noreferrer\">Platform Convergence Journey<\/a> the windows kernel was unified for Xbox, Windows 8, and Windows Phone 8 with introduction of Windows 8. Windows 8.1 then brought together the app model. Even then, under the term Universal App, it was possible \u2013 although a bit cumbersome \u2013 to develop a Windows Store App with a single app identity and the same codebase for desktops and smartphones.<\/p>\n<div id=\"attachment_6036\" style=\"width: 680px\" class=\"wp-caption alignnone\"><img decoding=\"async\" aria-describedby=\"caption-attachment-6036\" src=\"https:\/\/www.centigrade.de\/wordpress\/wp-content\/uploads\/PlatformConvergence-Illustration.png\" alt=\"Platform Convergence Journey\" width=\"670\" \/><p id=\"caption-attachment-6036\" class=\"wp-caption-text\">Platform Convergence Journey (Reference: <a title=\"Microsoft Virtual Academy - Developers Guide to Windows 10\" href=\"http:\/\/www.microsoftvirtualacademy.com\/training-courses\/a-developers-guide-to-windows-10\" target=\"_blank\" rel=\"noopener noreferrer\">Screencapture Microsoft Virtual Academy<\/a>)<\/p><\/div>\n<h3>The Windows 10 Philosophy<\/h3>\n<div id=\"attachment_6036\" style=\"width: 680px\" class=\"wp-caption alignnone\"><img decoding=\"async\" aria-describedby=\"caption-attachment-6036\" src=\"https:\/\/www.centigrade.de\/wordpress\/wp-content\/uploads\/Windows10-SampleScreen02.jpg\" alt=\"Windows 10 desktop and start menu\" width=\"670\" \/><p id=\"caption-attachment-6036\" class=\"wp-caption-text\">Windows 10 desktop and start menu (Reference: <a title=\"MS News Center (Windows 10)\" href=\"http:\/\/news.microsoft.com\/?attachment_id=115511\" target=\"_blank\" rel=\"noopener noreferrer\">Microsoft News Center<\/a>)<\/p><\/div>\n<p>At first sight it appears as though Windows 10 takes a step backwards. From the viewpoint of a desktop user that may be right. Windows Store Apps are able to run in a window, there is a classical start menu in combination with some tiles, and the touchscreen interaction is not assumed as the default. The UI is only adapted to this if Windows is running in tablet mode. But from the point of view of a developer Microsoft is consequently targeting the unification: in future there will be no separation of Windows versions for different devices anymore. <em>The Windows 10<\/em> will run on all devices, be it a smartphone, desktop, Xbox, Surface Hub, or even HoloLens or IoT devices like the RaspberryPi. On the so-called <a title=\"Guide to Universal Windows Platform (UWP) apps\" href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/dn894631.aspx\" target=\"_blank\" rel=\"noopener noreferrer\">Universal Windows Platform<\/a> a future Windows App will likewise run on all devices \u2013 like in the true meaning of <em>write once, deploy everywhere<\/em>.<\/p>\n<div id=\"attachment_6036\" style=\"width: 680px\" class=\"wp-caption alignnone\"><img decoding=\"async\" aria-describedby=\"caption-attachment-6036\" src=\"https:\/\/www.centigrade.de\/wordpress\/wp-content\/uploads\/UniversalWindowsPlatform-Illustration.png\" alt=\"Universal Windows Platform\" width=\"670\" \/><p id=\"caption-attachment-6036\" class=\"wp-caption-text\">Universal Windows Platform (Reference: <a title=\"MS Blog (First Look at the Windows 10 Universal App Platform)\" href=\"http:\/\/blogs.windows.com\/buildingapps\/2015\/03\/02\/a-first-look-at-the-windows-10-universal-app-platform\/\" target=\"_blank\" rel=\"noopener noreferrer\">Microsoft Blog<\/a>)<\/p><\/div>\n<p>Hence the developer will create one app \u2013 a truly, single binary \u2013 which will be deployed and run across all devices. However an application should by no means appear the same on all devices. In fact the developers are supposed to adapt the UI for the different devices, be it a smartwatch, a mobile line-of-business app, a desktop application or a UI for controlling a refrigerator in the internet of things. By using the <a title=\"Wikipedia: MVVM\" href=\"http:\/\/en.wikipedia.org\/wiki\/Model_View_ViewModel\" target=\"_blank\" rel=\"noopener noreferrer\">MVVM Pattern<\/a> a clean separation of concerns is feasible. Because of that the internal business logic can be isolated from the interchangeable, customizable and highly optimized presentation layer.<\/p>\n<div id=\"attachment_6216\" style=\"width: 680px\" class=\"wp-caption alignnone\"><img decoding=\"async\" aria-describedby=\"caption-attachment-6216\" class=\"size-full wp-image-6216\" src=\"https:\/\/www.centigrade.de\/wordpress\/wp-content\/uploads\/MVVM-Illustration-Centigrade1.png\" alt=\"MVVM: Model-View-ViewModel software architecture\" width=\"670\" srcset=\"https:\/\/www.centigrade.de\/wordpress\/wp-content\/uploads\/MVVM-Illustration-Centigrade1.png 2560w, https:\/\/www.centigrade.de\/wordpress\/wp-content\/uploads\/MVVM-Illustration-Centigrade1-300x169.png 300w, https:\/\/www.centigrade.de\/wordpress\/wp-content\/uploads\/MVVM-Illustration-Centigrade1-1024x576.png 1024w\" sizes=\"(max-width: 2560px) 100vw, 2560px\" \/><p id=\"caption-attachment-6216\" class=\"wp-caption-text\">MVVM: Model-View-ViewModel software architecture<\/p><\/div>\n<h3>Adaptive UIs<\/h3>\n<p>What does such a customization look like? What has to be adjusted for different devices and where? Which tools are available to the developer to adjust the UI? How can different device families technically be filtered and customizations made according to this information?<\/p>\n<p>The most intuitive component when thinking about different devices may be the form factors, like display size, resolution and the resulting physical \u2013 that is the one given by the device \u2013 pixel density. And in connection with that the distance between the user and the device \u2013 the view distance. To shortly summarize this: a higher <a title=\"Centigrade Blog: Aufl\u00f6sungsunabh\u00e4ngiges Icon Design\" href=\"http:\/\/www.centigrade.de\/en\/blog\/resolution-independent-icon-design-part-1\/\" target=\"_blank\" rel=\"noopener noreferrer\">physical resolution<\/a> on a smaller physical diagonal display size results in a higher pixel density also known as PPI (pixel per inch). This is even more important when the viewer is very close to the device. Therefore high density displays for smartphones are rather the rule than the exception. High PPI can be used to either fit more content into the same space \u2013 which only makes sense to a certain degree \u2013 or to display the same content in higher quality. Circular shapes, that are always approximations on digital devices, will come closer to their ideal representation. The user interface of the application will appear crisp and smooth to the user.<\/p>\n<p>Often it is not enough to only focus on these factors. Coming from the web development, <a title=\"Wikipedia: Responsive Webdesign\" href=\"http:\/\/en.wikipedia.org\/wiki\/Responsive_web_design\" target=\"_blank\" rel=\"noopener noreferrer\"><em>Responsive Design<\/em><\/a> can be used to differentiate between desktops and smartphones based on the resolution. A two column layout will be made into a one column layout, only the most relevant content will be displayed or moved to second levels of navigation. This is a first step that quickly reaches its limits. Responsive Design is a rather technical consideration that only reacts to device parameters. If the specific user role and the usage scenario is also considered during the UX design process, one will achieve remarkably better, and more intuitive results. This primary consideration of the user is called <em>Contextual Design<\/em>.<\/p>\n<h3>Contextual Design<\/h3>\n<div id=\"attachment_6027\" style=\"width: 310px\" class=\"wp-caption alignleft\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-6027\" class=\"size-medium wp-image-6027\" src=\"https:\/\/www.centigrade.de\/wordpress\/wp-content\/uploads\/Microsoft-HoloLens-Device-300x169.jpg\" alt=\"Microsoft HoloLens\" width=\"300\" height=\"169\" srcset=\"https:\/\/www.centigrade.de\/wordpress\/wp-content\/uploads\/Microsoft-HoloLens-Device-300x169.jpg 300w, https:\/\/www.centigrade.de\/wordpress\/wp-content\/uploads\/Microsoft-HoloLens-Device-1024x576.jpg 1024w, https:\/\/www.centigrade.de\/wordpress\/wp-content\/uploads\/Microsoft-HoloLens-Device.jpg 1440w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><p id=\"caption-attachment-6027\" class=\"wp-caption-text\">Microsoft HoloLens (Reference: <a title=\"MS News Center (HoloLens)\" href=\"http:\/\/news.microsoft.com\/?attachment_id=197511\" target=\"_blank\" rel=\"noopener noreferrer\">Microsoft News Center<\/a>)<\/p><\/div>\n<p>Virtual reality and augmented reality applications are the best examples to illustrate this, since they greatly benefit from Contextual Design. Because, what does the term resolution mean for this device family? A high resolution for a VR-glass is in the first place important in order to avoid the so-called <a title=\"Wikipedia: Screen-doof effect\" href=\"http:\/\/en.wikipedia.org\/wiki\/Screen-door_effect\" target=\"_blank\" rel=\"noopener noreferrer\"><em>Screen-door effect<\/em><\/a>. This is due to the small distance between the display and the user\u2019s eye. However, what is even more important is where the UI is placed inside the 3D scene of the VR- or AR-application, because this will have an impact on the perceived resolution. UI elements could thereby be placed in the real world like recently demonstrated in <a title=\"Keynote Build 2015\" href=\"http:\/\/channel9.msdn.com\/Events\/Build\/2015\/KEY01\" target=\"_blank\" rel=\"noopener noreferrer\">Microsoft\u2019s keynote talk of the Build conference 2015<\/a>. It is hard to tackle this challenge with classical Responsive Design.<\/p>\n<div id=\"attachment_6036\" style=\"width: 680px\" class=\"wp-caption alignnone\"><img decoding=\"async\" aria-describedby=\"caption-attachment-6036\" src=\"https:\/\/www.centigrade.de\/wordpress\/wp-content\/uploads\/Microsoft-HoloLens-Skype.jpg\" alt=\"Microsoft HoloLens: Concept for an augmented reality application\" width=\"670\" \/><p id=\"caption-attachment-6036\" class=\"wp-caption-text\">Microsoft HoloLens: Concept for an augmented reality application (Reference: <a title=\"MS News Center (HoloLens)\" href=\"http:\/\/news.microsoft.com\/?attachment_id=152383\" target=\"_blank\" rel=\"noopener noreferrer\">Microsoft News Center<\/a>)<\/p><\/div>\n<p>Though apart from VR or AR, it is already sufficient to simply take a look at the desktop \u2013 meaning a stationary computer \u2013 be it an office pc, a conference monitor or a huge screen in a space station&#8217;s control room. In these situations one will quickly end up in scenarios where Responsive Design is not enough.<\/p>\n<div id=\"attachment_6036\" style=\"width: 680px\" class=\"wp-caption alignnone\"><img decoding=\"async\" aria-describedby=\"caption-attachment-6036\" src=\"https:\/\/www.centigrade.de\/wordpress\/wp-content\/uploads\/ESA-ControlRoom.jpg\" alt=\"Control room of the esa space station\" width=\"670\" \/><p id=\"caption-attachment-6036\" class=\"wp-caption-text\">Control room of the esa space station (Reference: <a title=\"Gallery esa Homepage\" href=\"http:\/\/www.esa.int\/spaceinimages\/Images\/2012\/06\/Main_Control_Room_at_ESA_s_Space_Operations_Centre\" target=\"_blank\" rel=\"noopener noreferrer\">esa Homepage<\/a>)<\/p><\/div>\n<p>Also, there are some developers who work with their screens in portrait mode. Are there applications that react to whether the monitor is rotated 90 degrees? Pair-programming sessions or code reviews in a walkthrough manner include multiple persons in front of a single display. Some people are closer to the screen than others. Which applications take these scenarios into consideration?<\/p>\n<div id=\"attachment_6036\" style=\"width: 680px\" class=\"wp-caption alignnone\"><img decoding=\"async\" aria-describedby=\"caption-attachment-6036\" src=\"https:\/\/www.centigrade.de\/wordpress\/wp-content\/uploads\/Typical-Office.jpg\" alt=\"A typical desktop?\" width=\"670\" \/><p id=\"caption-attachment-6036\" class=\"wp-caption-text\">A typical desktop?<\/p><\/div>\n<p><a title=\"Microsoft Surface Hub\" href=\"https:\/\/www.microsoft.com\/microsoft-surface-hub\/en-us\" target=\"_blank\" rel=\"noopener noreferrer\">Microsoft&#8217;s Surface Hub<\/a> is a huge 84 inches conference screen with multiple cameras, directed microphones and pen input. The presenter stands right beside the screen and can write directly onto the application, while viewers sit in quite a distance away, and some attendees are only connected via remote while still seeing the same content on their local computer. So far, I have not come across any meeting application that is \u2013 without major adjustments \u2013 optimized for this scenario.<\/p>\n<div id=\"attachment_6036\" style=\"width: 680px\" class=\"wp-caption alignnone\"><img decoding=\"async\" aria-describedby=\"caption-attachment-6036\" src=\"https:\/\/www.centigrade.de\/wordpress\/wp-content\/uploads\/Microsoft-SurfaceHub-Meeting01.jpg\" alt=\"Microsoft Surface Hub in meetings\" width=\"670\" \/><p id=\"caption-attachment-6036\" class=\"wp-caption-text\">Microsoft Surface Hub in meetings (Reference: <a title=\"MS News Center (Surface Hub)\" href=\"http:\/\/news.microsoft.com\/?attachment_id=197511\" target=\"_blank\" rel=\"noopener noreferrer\">Microsoft News Center<\/a>)<\/p><\/div>\n<p>Universal Apps targeting a broad audience will be faced with these kinds of challenges, which can only be solved by Contextual UI Design. In doing so, an application will know its usage scenario and will be able to react accordingly. The view distance can e.g. be detected through eye-tracking sensors on the device. An app will know whether it is in portrait mode and will be able to optimize its content for this scenario. Only if a device has a microphone as input type, the push-to-talk functionality will be visible. There are numerous challenges that can only be solved properly if the user is taken into account. From a technical perspective it seems like very hard additional work. Processing eye-tracking information and reacting with layout and content optimizations seem to be a herculean task. However Windows 10, Visual Studio 2015 and the Universal App Platform support the developer with new features to create context sensitive software with great user experience. We will now focus on some of these tools.<\/p>\n<h3>UWP Features in Windows 10<\/h3>\n<p>Like the <a title=\"WPF Text Measurement Units\" href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/desktop\/learnwin32\/dpi-and-device-independent-pixels\" target=\"_blank\" rel=\"noopener noreferrer\">device independent pixels<\/a> in WPF, Microsoft continues to focus on a term for abstract pixel information and introduces so-called <a title=\"Designing with effective pixels\" href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/windows\/apps\/dn958435.aspx#Designing_with_effective_pixels\" target=\"_blank\" rel=\"noopener noreferrer\"><em>effective pixels<\/em><\/a>. These are based on the pixel density of the device and a heuristic view distance. It results in abstract pixel information, so that a developer has to care less about physical details. Elements <em>appear<\/em> the same size to the user across all devices.<\/p>\n<p>Furthermore the <a title=\"RelativePanel (MSDN)\" href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/windows.ui.xaml.controls.relativepanel.aspx\" target=\"_blank\" rel=\"noopener noreferrer\">RelativePanel<\/a> is a new layout container intended to structure elements inside this container in relation to each other. This is extremely powerful when the layout is supposed to change and adapt dynamically. Prior to that you had to implement a custom panel or make complex adjustments to a Grid.<\/p>\n<p>In order to react to different device families and form factors, we will now take a look at the so-called <a title=\"Guide to Universal Windows Platform (UWP) apps\" href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/dn894631.aspx#Use_visual_state_triggers_to_build_UI_that_can_adapt_to_available_screen_space\" target=\"_blank\" rel=\"noopener noreferrer\">VisualState-Triggers<\/a>. Microsoft proposes to use the VisualStateManager and VisualStates for different view states.<\/p>\n<h2>Implementation sample: A custom VisualState-Trigger<\/h2>\n<p>Let\u2019s imagine the following scenario: The user owns a monitor which is able to measure the current view distance (e.g. via webcam, a head tracking system, infrared, the Kinect etc.). As a developer I want my application to adjust its font size according to the view distance. The font size should always appear the same size to the users. They could be very close to the screen (because they may take notes with a pen on a touch sensitive display), in a normal view distance, or rather further away while having a pair-session. As a UI developer I have to technically detect these changes to finally respond to them in XAML in an easy way. We will now implement this while not focusing on crafting a beautiful and complete application. In fact, we will focus on demonstrating the newly available features of the platform.<\/p>\n<p>First of all we will create a new <em>Windows Universal App<\/em> project, open the <span style=\"font-family: Consolas, 'Courier New', Courier, Monospace;\">MainPage.xaml<\/span> and place some text in it. At the same time we introduce two visual states as a showcase for the near and far view distance:<br \/>\n<code><\/code><\/p>\n<pre class=\"csharpcode\" style=\"font-size: medium; color: black; font-family: Consolas, 'Courier New', Courier, Monospace; background-color: #ffffff;\"><span class=\"kwrd\" style=\"color: #0000ff;\">&lt;<\/span><span class=\"html\" style=\"color: #800000;\">Grid<\/span> <span class=\"attr\" style=\"color: #ff0000;\">Margin<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">=\"25\"<\/span> <span class=\"attr\" style=\"color: #ff0000;\">Background<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">=\"White\"<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n   <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;<\/span><span class=\"html\" style=\"color: #800000;\">VisualStateManager.VisualStateGroups<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n      <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;<\/span><span class=\"html\" style=\"color: #800000;\">VisualStateGroup<\/span> <span class=\"attr\" style=\"color: #ff0000;\">x:Name<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">=\"CommonStates\"<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n         <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;<\/span><span class=\"html\" style=\"color: #800000;\">VisualState<\/span> <span class=\"attr\" style=\"color: #ff0000;\">x:Name<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">=\"Near\"<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n            <span class=\"rem\" style=\"color: #008000;\">&lt;!-- Trigger and reaction missing for now. --&gt;<\/span>\r\n         <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;\/<\/span><span class=\"html\" style=\"color: #800000;\">VisualState<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n         <span class=\"rem\" style=\"color: #008000;\">&lt;!-- Here could be more states \u2026 --&gt;<\/span>\r\n         <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;<\/span><span class=\"html\" style=\"color: #800000;\">VisualState<\/span> <span class=\"attr\" style=\"color: #ff0000;\">x:Name<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">=\"Far\"<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n            <span class=\"rem\" style=\"color: #008000;\">&lt;!-- Trigger and reaction missing for now. --&gt;<\/span>\r\n         <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;\/<\/span><span class=\"html\" style=\"color: #800000;\">VisualState<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n      <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;\/<\/span><span class=\"html\" style=\"color: #800000;\">VisualStateGroup<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n   <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;\/<\/span><span class=\"html\" style=\"color: #800000;\">VisualStateManager.VisualStateGroups<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n   <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;<\/span><span class=\"html\" style=\"color: #800000;\">TextBlock<\/span> <span class=\"attr\" style=\"color: #ff0000;\">x:Name<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">=\"Output\"<\/span>\r\n      <span class=\"attr\" style=\"color: #ff0000;\">FontSize<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">=\"20\"<\/span>\r\n      <span class=\"attr\" style=\"color: #ff0000;\">Text<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">=\"Lorem ipsum dolor sit amet, consetetur\u2026\"<\/span>\r\n      <span class=\"attr\" style=\"color: #ff0000;\">TextTrimming<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">=\"CharacterEllipsis\"<\/span>\r\n      <span class=\"attr\" style=\"color: #ff0000;\">TextWrapping<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">=\"Wrap\"<\/span> <span class=\"kwrd\" style=\"color: #0000ff;\">\/&gt;<\/span>\r\n<span class=\"kwrd\" style=\"color: #0000ff;\">&lt;\/<\/span><span class=\"html\" style=\"color: #800000;\">Grid<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Currently Microsoft only ships the <span style=\"font-family: Consolas, 'Courier New', Courier, Monospace;\"><a title=\"AdaptiveTrigger (MSDN)\" href=\"https:\/\/msdn.microsoft.com\/en-uS\/office\/office365\/windows.ui.xaml.adaptivetrigger.aspx\" target=\"_blank\" rel=\"noopener noreferrer\">AdaptiveTrigger<\/a><\/span>. This trigger can only react to the screen size (in effective pixels). So, at the moment there is no built-in feature to fulfill our requirements. Fortunately we can write our own trigger and use it in XAML. Let&#8217;s look at the following example: as soon as the view distance is less than 12 inches we want to switch to our near state. We can represent this as a trigger in the following way:<br \/>\n<code><\/code><\/p>\n<pre class=\"csharpcode\" style=\"font-size: medium; color: black; font-family: Consolas, 'Courier New', Courier, Monospace; background-color: #ffffff;\"><span class=\"kwrd\" style=\"color: #0000ff;\">&lt;<\/span><span class=\"html\" style=\"color: #800000;\">VisualState<\/span> <span class=\"attr\" style=\"color: #ff0000;\">x:Name<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">=\"Near\"<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n   <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;<\/span><span class=\"html\" style=\"color: #800000;\">VisualState.StateTriggers<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n      <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;<\/span><span class=\"html\" style=\"color: #800000;\">triggers:ViewDistanceTrigger<\/span> <span class=\"attr\" style=\"color: #ff0000;\">MaxViewDistance<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">=\"12\"<\/span> <span class=\"kwrd\" style=\"color: #0000ff;\">\/&gt;<\/span>\r\n   <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;\/<\/span><span class=\"html\" style=\"color: #800000;\">VisualState.StateTriggers<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n   <span class=\"rem\" style=\"color: #008000;\">&lt;!-- What to do? --&gt;<\/span>\r\n<span class=\"kwrd\" style=\"color: #0000ff;\">&lt;\/<\/span><span class=\"html\" style=\"color: #800000;\">VisualState<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>This trigger must now be implemented. Therefore you can inherit from <span style=\"font-family: Consolas, 'Courier New', Courier, Monospace;\"><a title=\"StateTriggerBase (MSDN)\" href=\"https:\/\/msdn.microsoft.com\/en-uS\/office\/office365\/windows.ui.xaml.statetriggerbase.aspx\" target=\"_blank\" rel=\"noopener noreferrer\">StateTriggerBase<\/a><\/span> and use the method <span style=\"font-family: Consolas, 'Courier New', Courier, Monospace;\">SetActive<\/span> to (de)active the trigger. The VisualState defined in XAML becomes active as soon as <span style=\"font-family: Consolas, 'Courier New', Courier, Monospace;\">SetActive(true)<\/span> is called. The trigger could for instance use a component called <span style=\"font-family: Consolas, 'Courier New', Courier, Monospace;\">IViewDistanceDetector<\/span>, which is responsible for detecting change of the view distance:<br \/>\n<code><\/code><\/p>\n<pre class=\"csharpcode\" style=\"font-size: medium; color: black; font-family: Consolas, 'Courier New', Courier, Monospace; background-color: #ffffff;\"><span class=\"kwrd\" style=\"color: #0000ff;\">public<\/span> <span class=\"kwrd\" style=\"color: #0000ff;\">class<\/span> ViewDistanceTrigger : StateTriggerBase\r\n{\r\n   <span class=\"kwrd\" style=\"color: #0000ff;\">public<\/span> <span class=\"kwrd\" style=\"color: #0000ff;\">double<\/span> MinViewDistance { <span class=\"kwrd\" style=\"color: #0000ff;\">get<\/span>; <span class=\"kwrd\" style=\"color: #0000ff;\">set<\/span>; } = 0;\r\n   <span class=\"kwrd\" style=\"color: #0000ff;\">public<\/span> <span class=\"kwrd\" style=\"color: #0000ff;\">double<\/span> MaxViewDistance { <span class=\"kwrd\" style=\"color: #0000ff;\">get<\/span>; <span class=\"kwrd\" style=\"color: #0000ff;\">set<\/span>; } = <span class=\"kwrd\" style=\"color: #0000ff;\">double<\/span>.PositiveInfinity;\r\n\r\n   <span class=\"kwrd\" style=\"color: #0000ff;\">private<\/span> IViewDistanceDetector viewDistanceDetector;\r\n\r\n   <span class=\"kwrd\" style=\"color: #0000ff;\">public<\/span> ViewDistanceTrigger()\r\n   {\r\n      viewDistanceDetector = new ViewDistanceDetector();\r\n      viewDistanceDetector.ViewDistanceChanged +=\r\n\t     ViewDistanceDetector_ViewDistanceChanged;\r\n   }\r\n\r\n   <span class=\"kwrd\" style=\"color: #0000ff;\">private<\/span> void ViewDistanceDetector_ViewDistanceChanged\r\n      (<span class=\"kwrd\" style=\"color: #0000ff;\">object<\/span> sender, ViewDistanceChangedEventArgs eventArgs)\r\n   {\r\n      <span class=\"kwrd\" style=\"color: #0000ff;\">double<\/span> currentViewDistance = eventArgs.ViewDistanceInInch;\r\n   \r\n      <span class=\"kwrd\" style=\"color: #0000ff;\">if<\/span>((currentViewDistance &gt;= MinViewDistance)\r\n\t     &amp;&amp; (currentViewDistance &lt;= MaxViewDistance))\r\n      {\r\n         SetActive(<span class=\"kwrd\" style=\"color: #0000ff;\">true<\/span>);\r\n      }\r\n      <span class=\"kwrd\" style=\"color: #0000ff;\">else<\/span>\r\n      {\r\n         SetActive(<span class=\"kwrd\" style=\"color: #0000ff;\">false<\/span>);\r\n      }\r\n   }\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>To keep it simple, we will only change the font size of our TextBlock. With help from the new <a title=\"VisualState.Setters (MSDN)\" href=\"https:\/\/msdn.microsoft.com\/en-uS\/office\/office365\/windows.ui.xaml.visualstate.setters.aspx\" target=\"_blank\" rel=\"noopener noreferrer\">VisualState setters<\/a> it is easy to apply discrete changes to the values without a complex definition of Storyboards. This feature is very handy for initial state changes:<br \/>\n<code><\/code><\/p>\n<pre class=\"csharpcode\" style=\"font-size: medium; color: black; font-family: Consolas, 'Courier New', Courier, Monospace; background-color: #ffffff;\"><span class=\"kwrd\" style=\"color: #0000ff;\">&lt;<\/span><span class=\"html\" style=\"color: #800000;\">VisualState<\/span> <span class=\"attr\" style=\"color: #ff0000;\">x:Name<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">=\"Near\"<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n   <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;<\/span><span class=\"html\" style=\"color: #800000;\">VisualState.StateTriggers<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n      <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;<\/span><span class=\"html\" style=\"color: #800000;\">triggers:ViewDistanceTrigger<\/span> <span class=\"attr\" style=\"color: #ff0000;\">MaxViewDistance<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">=\"12\"<\/span> <span class=\"kwrd\" style=\"color: #0000ff;\">\/&gt;<\/span>\r\n   <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;\/<\/span><span class=\"html\" style=\"color: #800000;\">VisualState.StateTriggers<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n   <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;<\/span><span class=\"html\" style=\"color: #800000;\">VisualState.Setters<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n      <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;<\/span><span class=\"html\" style=\"color: #800000;\">Setter<\/span> \r\n         <span class=\"attr\" style=\"color: #ff0000;\">Target<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">=\"Output.FontSize\"<\/span>\r\n         <span class=\"attr\" style=\"color: #ff0000;\">Value<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">=\"{StaticResource FontSize.Small}\"<\/span> <span class=\"kwrd\" style=\"color: #0000ff;\">\/&gt;<\/span>\r\n   <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;\/<\/span><span class=\"html\" style=\"color: #800000;\">VisualState.Setters<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n<span class=\"kwrd\" style=\"color: #0000ff;\">&lt;\/<\/span><span class=\"html\" style=\"color: #800000;\">VisualState<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n<span class=\"kwrd\" style=\"color: #0000ff;\">&lt;<\/span><span class=\"html\" style=\"color: #800000;\">VisualState<\/span> <span class=\"attr\" style=\"color: #ff0000;\">x:Name<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">=\"Far\"<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n   <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;<\/span><span class=\"html\" style=\"color: #800000;\">VisualState.StateTriggers<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n      <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;<\/span><span class=\"html\" style=\"color: #800000;\">triggers:ViewDistanceTrigger<\/span> <span class=\"attr\" style=\"color: #ff0000;\">MaxViewDistance<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">=\"25\"<\/span> <span class=\"kwrd\" style=\"color: #0000ff;\">\/&gt;<\/span>\r\n   <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;\/<\/span><span class=\"html\" style=\"color: #800000;\">VisualState.StateTriggers<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n   <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;<\/span><span class=\"html\" style=\"color: #800000;\">VisualState.Setters<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n      <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;<\/span><span class=\"html\" style=\"color: #800000;\">Setter<\/span> \r\n         <span class=\"attr\" style=\"color: #ff0000;\">Target<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">=\"Output.FontSize\"<\/span>\r\n         <span class=\"attr\" style=\"color: #ff0000;\">Value<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">=\"{StaticResource FontSize.Large}\"<\/span> <span class=\"kwrd\" style=\"color: #0000ff;\">\/&gt;<\/span>\r\n   <span class=\"kwrd\" style=\"color: #0000ff;\">&lt;\/<\/span><span class=\"html\" style=\"color: #800000;\">VisualState.Setters<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n<span class=\"kwrd\" style=\"color: #0000ff;\">&lt;\/<\/span><span class=\"html\" style=\"color: #800000;\">VisualState<\/span><span class=\"kwrd\" style=\"color: #0000ff;\">&gt;<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Of course an animated, smooth transition and more states inbetween would be nice. However we only wanted to show how to write custom triggers in a Universal App to make adaptive and context sensitive changes to the UI in a compact way. It is clear that this concept can be expanded to a variety of contextual information: is the screen in portrait mode? Do I have a microphone for speech input? Is an Xbox controller conntected to my device? Is my application running on a specific device family? All this information could comfortably be stored inside triggers. It is to be hoped that Microsoft will provide more built-in triggers that will release the developer from the burden to write his own ones.<\/p>\n<h3>Conclusion<\/h3>\n<p>As we have just seen, Windows 10 and the Universal Windows Platform will provide us with a couple of aids to optimize the UI for different devices. Microsoft is responsible for doing that as they promise that a single app will run across all devices. Having that said, these tools can also be utilized to enhance the experience of desktop applications. Insights we gained while developing smartphone UIs for different user scenarios and roles can be transformed to the desktop world. Even in fixed desktop environments there is a variety of contexts and diverse possibilities for interaction. We have to react to all those factors in a proper way. Concerning the UX design the desktop hasn\u2019t come to an end yet. There still is a wide range of innovative concepts hidden that should be explored and eventually used to create astonishing applications.<\/p>\n<h3>Download<\/h3>\n<p>If you would like to take a closer look at\u00a0my presentation slides, code samples\u00a0from the DWX or code snippets from this blog, you can do so:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.centigrade.de\/wordpress\/wp-content\/uploads\/NextGenerationDesktopUIs-Windows10-dotnetCologne-DWX.pdf\">PDF: Presentation slides: Next Generation Desktop UIs for Windows 10<\/a><\/li>\n<li><a href=\"https:\/\/www.centigrade.de\/wordpress\/wp-content\/uploads\/DavidWuerfel_NextGenDesktop-CodeSamples-DWX.zip\">ZIP: Code samples from the DWX<\/a><\/li>\n<li><a href=\"https:\/\/www.centigrade.de\/wordpress\/wp-content\/uploads\/DavidWuerfel_NextGenDesktop-Blog-CodeSnippets-ViewDistanceSample.zip\">ZIP: Code Snippets from this blog<\/a><\/li>\n<\/ul>\n<div class=\"trademark\">All trademarks and product names used on this website are the properties of their respective owners and are used solely for descriptive purposes.<\/div>\n","protected":false},"author":42,"featured_media":0,"template":"","tags":[430,436,428,429,29,426,189,427],"class_list":["post-6143","blog","type-blog","status-publish","hentry","tag-contextual-design","tag-dotnet-cologne","tag-universal-apps","tag-universal-windows-platform","tag-user-interface-design","tag-windows-10","tag-windows-8","tag-windows-8-1"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.centigrade.de\/en\/wp-json\/wp\/v2\/blog\/6143","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.centigrade.de\/en\/wp-json\/wp\/v2\/blog"}],"about":[{"href":"https:\/\/www.centigrade.de\/en\/wp-json\/wp\/v2\/types\/blog"}],"author":[{"embeddable":true,"href":"https:\/\/www.centigrade.de\/en\/wp-json\/wp\/v2\/users\/42"}],"version-history":[{"count":0,"href":"https:\/\/www.centigrade.de\/en\/wp-json\/wp\/v2\/blog\/6143\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.centigrade.de\/en\/wp-json\/wp\/v2\/media?parent=6143"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.centigrade.de\/en\/wp-json\/wp\/v2\/tags?post=6143"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}