Compiled Experience Windows Platform Development http://compiledexperience.com en Wed, 02 Mar 2016 00:50:10 +0000 Wed, 02 Mar 2016 00:50:10 +0000 Xamarin acquisition thoughts <p>Last week it was <a href="https://weblogs.asp.net/scottgu/welcoming-the-xamarin-team-to-microsoft">announced</a> that Microsoft would be acquiring <a href="https://xamarin.com/">Xamarin</a>, the popular toolset for building cross platform mobile apps with C#.</p> <p>I presented a number of talks last year on <a href="http://compiledexperience.com/blog/posts/latest-talks">building cross platforms mobile apps with Xamarin</a> that you can view online.</p> <p>It’s certainly an interesting piece of news, most people expected this to be announced at last year’s Build (or even the year before). Back then there was a school of though that it was better to keep Xamarin as a close partner rather than acquiring them. The belief was that this would better enable Xamarin to work with other <em>“competitors</em>” such as Apple, Google and IBM.</p> <p>I think now in 2016 it makes a lot of sense, the developer pick up of UWP is slow (IMO because there’s currently on one platform with the desktop) and Microsoft need ways to drive more apps to the UWP platform.</p> <p>Last year most of the announcements were around the application bridges, Astora, Centennial, Islandwood and Windsor (Android, Classic Windows, iOS and Web) as a way to bring more apps into the store (and hopefully the platform as well). Since the Astoria has been cancelled, we haven’t see much of Centennial but Islandwood is looking really good.</p> <p>This strategy didn’t make themselves popular with a lot of Windows developers who thought these technologies would render them obsolete (a line of thought I didn’t wholly agree with).</p> <p>Microsoft appears to be positioning themselves quite nicely in the cross platform cloud and developer tools space (I think it’s telling that announcement was on Scott Guthrie’s blog). By having a tool-set where it isn’t about migrating old apps but creating new cross platform apps I think they can better push Windows as a third platform as well as Android and iOS.</p> <p>My thoughts on what may change over the next year or so.</p> <ul> <li>Xamarin subscription to be rolled into MSDN.</li> <li>Test Cloud to be part of Azure.</li> <li>Some people think Xamarin Studio may merge with Visual Studio Code, I doubt that. We may see the end of Xamarin Studio with efforts focussed on Visual Studio.</li> <li>Android Player to be deprecated in favour of Visual Studio Android Emulator.</li> <li>Hopefully better support for the Windows platforms in Xamarin.Forms, the default renderers are terrible.</li> <li>Xamarin Insights to be merged with Application Insights / HockeyApp.</li> </ul> <p>Looking forward to what will be announced at Build, sadly will be missing this year though.</p> Tue, 01 Mar 2016 00:00:00 +0000 http://compiledexperience.com/blog/posts/xamarin-acquisition http://compiledexperience.com/blog/posts/xamarin-acquisition nigel.sampson@compiledexperience.com (Nigel Sampson) Caliburn.Micro 3.0.0 <p>After a <strong>prolonged</strong> period in beta <a href="http://caliburnmicro.com/announcements/3.0.0">Caliburn.Micro 3.0.0</a> has just been pushed to nuget.</p> <p>This release stuck around in beta a lot longer than I wanted, mostly due to a series of overlapping circumstances. Some issue comes up where it wouldn’t make sense to release till it has been resolved, by that time another has cropped up. This is pretty normal for most projects but when only some of the issues are under your control it becomes very frustrating.</p> <p>I’m really glad <a href="https://xamarin.com/forms">Xamarin.Forms</a> made it into this release, it’s not fully featured without programmatic access to <code class="highlighter-rouge">x:Name</code> but it’s still a great story. The idea we can have a view model that is able to be used across all mobile platforms and even older desktop platforms such as WPF at the same time is really compelling.</p> <p>Check out the full <a href="http://caliburnmicro.com/announcements/3.0.0">announcement</a> for the full details for the release.</p> Tue, 01 Mar 2016 00:00:00 +0000 http://compiledexperience.com/blog/posts/caliburn.micro-3.0.0 http://compiledexperience.com/blog/posts/caliburn.micro-3.0.0 nigel.sampson@compiledexperience.com (Nigel Sampson) Why won't my Jekyll post appear? <p>On February 2nd GitHub Pages (which hosts this website) announced they were <a href="https://github.com/blog/2100-github-pages-now-faster-and-simpler-with-jekyll-3-0">now running with Jekyll 3.0.0</a> and there were a few changes required mostly around the standardisation on the <a href="http://kramdown.gettalong.org/">kramdown</a> Markdown engine.</p> <p>This morning writing the <a href="http://compiledexperience.com/blog/posts/behaviors-1.1.0">UWP XAML Behaviors 1.1.0 released</a> post I ran into a problem where no matter what I did the post wouldn’t show. Other changes to the site were being generated correctly and I wasn’t receiving an error email from GitHub so I was reasonably stumped.</p> <p>Whenever I write a post I tend to date it with local time which depending on the time of day could be a day ahead of the server which hasn’t been a problem till now.</p> <p>In Jekyll 2.x future posts would be published by default, in 3.x they will not, this is outlined in the <a href="http://jekyllrb.com/docs/upgrading/2-to-3/#future-posts">Upgrading from 2.x to 3.x</a> documentation.</p> <p>In the end I solved this by adding the following to <code class="highlighter-rouge">_config.yml</code>.</p> <div class="highlighter-rouge"><pre class="highlight"><code>future: true </code></pre> </div> <p>I could have also solved this by setting the timezone in configuration as well.</p> <p>Hope this helps someone.</p> Wed, 24 Feb 2016 00:00:00 +0000 http://compiledexperience.com/blog/posts/jekyll-future-posts http://compiledexperience.com/blog/posts/jekyll-future-posts nigel.sampson@compiledexperience.com (Nigel Sampson) UWP XAML Behaviors 1.1.0 released <p>Last year I had the privledge of being invited onto the project committee for <a href="https://blogs.windows.com/buildingapps/2015/11/30/xaml-behaviors-open-source-and-on-uwp/">newly open sourced XAML behaviors</a> project.</p> <p>Yesterday the <code class="highlighter-rouge">1.1.0</code> version of the package was released to <a href="https://www.nuget.org/packages/Microsoft.Xaml.Behaviors.Uwp.Managed/">nuget</a>. This fixed a <a href="https://github.com/Microsoft/XamlBehaviors/issues/55">nasty bug</a> in <code class="highlighter-rouge">EventTriggerBehavior</code> that was causing it to not correctly unsubscribe from the event on detach.</p> <p>This bug was holding up <code class="highlighter-rouge">3.0.0</code> final of Caliburn.Micro so I’m now looking at rolling out a release soon.</p> <p>If you’re looking to contribute to UWP XAML Behaviors the project is located on <a href="https://github.com/Microsoft/XamlBehaviors">Github</a>.</p> Wed, 24 Feb 2016 00:00:00 +0000 http://compiledexperience.com/blog/posts/behaviors-1.1.0 http://compiledexperience.com/blog/posts/behaviors-1.1.0 nigel.sampson@compiledexperience.com (Nigel Sampson) MVP Renewal <p>Pleased to say that I’ve been renewed as an Microsoft MVP for 2016. Lot’s to be done this month so hopefully some exciting things to announce.</p> Wed, 06 Jan 2016 00:00:00 +0000 http://compiledexperience.com/blog/posts/2016-mvp http://compiledexperience.com/blog/posts/2016-mvp nigel.sampson@compiledexperience.com (Nigel Sampson) Latest talks online <p>I’ve been doing a number of talks lately and most of them are now online.</p> <p>The first is <a href="https://channel9.msdn.com/Events/Ignite/Microsoft-Ignite-New-Zealand-2015/M347">Developing Cross Platform Mobile Apps with XAML and MVVM</a> which I delivered at Microsoft Ignite 2015, the recorded video and slides are available on the <a href="https://channel9.msdn.com/Events/Ignite/Microsoft-Ignite-New-Zealand-2015/M347">Channel 9</a> website.</p> <p>The second is <a href="http://1drv.ms/1OwWR5F">Xamarin 101</a> from the <a href="http://www.meetup.com/North-Shore-NET-User-Group/">North Shore .NET User Group</a>, no recording sadly but I’ve made the slides <a href="http://1drv.ms/1OwWR5F">publicly available</a>.</p> <p>Both talks used the same demos on <a href="https://github.com/nigel-sampson/talks/tree/master/cross-platform-mvvm">GitHub</a>.</p> <p>Hope people find these useful.</p> Thu, 01 Oct 2015 00:00:00 +0000 http://compiledexperience.com/blog/posts/latest-talks http://compiledexperience.com/blog/posts/latest-talks nigel.sampson@compiledexperience.com (Nigel Sampson) What's new in Windows 10 - Title Bar <p>Microsoft have finally started to show off what’s available in Windows 10 for us app developers. Over the next few days we can start to take a look at some of these changes and what it can mean. Today we’ll look at what options we have to configure the new window Title Bar.</p> <h2 id="disclaimer">Disclaimer</h2> <p>This was written using the initial release of the Windows 10 Developer Tools running on Windows 10 build 10041 and things will mostly change before final release. I’ll try to come back and keep these posts up to date as time goes on.</p> <h2 id="title-bar">Title Bar</h2> <p>Now that our apps will work look and work like any standard desktop application we’ll find them framed in a window with a title bar. By default the title bar will look like the image below with a grey bar. It will have the app name on the left and three standard windows buttons on the right.</p> <p><a href="/content/images/posts/default.png"><img width="600" src="/content/images/posts/default.png" /></a></p> <p>So what can we customise? Most things thankfully. The code below sets the text on the left to <strong>&lt;app name&gt; - My Custom Title</strong>. So it could be a good idea to update this each page of your app.</p> <div class="highlighter-rouge"><pre class="highlight"><code><span class="n">var</span> <span class="n">applicationView</span> <span class="p">=</span> <span class="n">ApplicationView</span><span class="p">.</span><span class="nf">GetForCurrentView</span><span class="p">();</span> <span class="n">applicationView</span><span class="p">.</span><span class="n">Title</span> <span class="p">=</span> <span class="s">"My Custom Title"</span><span class="p">;</span> </code></pre> </div> <p>The most likely thing we’re going to want to do is customise the colours. We can do that using the <code class="highlighter-rouge">TitleBar</code> property of <code class="highlighter-rouge">ApplicationView</code>.</p> <div class="highlighter-rouge"><pre class="highlight"><code><span class="n">var</span> <span class="n">applicationView</span> <span class="p">=</span> <span class="n">ApplicationView</span><span class="p">.</span><span class="nf">GetForCurrentView</span><span class="p">();</span> <span class="n">var</span> <span class="n">titleBar</span> <span class="p">=</span> <span class="n">applicationView</span><span class="p">.</span><span class="n">TitleBar</span><span class="p">;</span> <span class="n">titleBar</span><span class="p">.</span><span class="n">BackgroundColor</span> <span class="p">=</span> <span class="p">(</span><span class="n">Color</span><span class="p">)</span> <span class="n">Resources</span><span class="p">[</span><span class="s">"SidebarBackgroundColor"</span><span class="p">];</span> <span class="n">titleBar</span><span class="p">.</span><span class="n">ForegroundColor</span> <span class="p">=</span> <span class="n">Colors</span><span class="p">.</span><span class="n">White</span><span class="p">;</span> <span class="n">titleBar</span><span class="p">.</span><span class="n">ButtonBackgroundColor</span> <span class="p">=</span> <span class="p">(</span><span class="n">Color</span><span class="p">)</span> <span class="n">Resources</span><span class="p">[</span><span class="s">"LightSidebarBackgroundColor"</span><span class="p">];</span> <span class="n">titleBar</span><span class="p">.</span><span class="n">ButtonForegroundColor</span> <span class="p">=</span> <span class="n">Colors</span><span class="p">.</span><span class="n">White</span><span class="p">;</span> </code></pre> </div> <p>The first two properties change the background the bar itself and the colour of the title text. The second two set the background and foreground of the buttons. There’s actually a LOT of properties for the buttons covering their hover and pressed states. I’d recommend checking out the documentation on <a href="https://msdn.microsoft.com/en-ca/windows.ui.viewmanagement.applicationviewtitlebar">MSDN</a>.</p> <p>The code above gives us</p> <p><a href="/content/images/posts/colours.png"><img width="600" src="/content/images/posts/colours.png" /></a></p> <p>A third option is to remove the title bar altogether for that <em>chrome-less</em> look. We can use the <code class="highlighter-rouge">ExtendViewIntoTitleBar</code> property.</p> <div class="highlighter-rouge"><pre class="highlight"><code><span class="n">var</span> <span class="n">applicationView</span> <span class="p">=</span> <span class="n">ApplicationView</span><span class="p">.</span><span class="nf">GetForCurrentView</span><span class="p">();</span> <span class="n">var</span> <span class="n">titleBar</span> <span class="p">=</span> <span class="n">applicationView</span><span class="p">.</span><span class="n">TitleBar</span><span class="p">;</span> <span class="n">titleBar</span><span class="p">.</span><span class="n">ExtendViewIntoTitleBar</span> <span class="p">=</span> <span class="k">true</span><span class="p">;</span> <span class="n">titleBar</span><span class="p">.</span><span class="n">ButtonBackgroundColor</span> <span class="p">=</span> <span class="p">(</span><span class="n">Color</span><span class="p">)</span> <span class="n">Resources</span><span class="p">[</span><span class="s">"LightSidebarBackgroundColor"</span><span class="p">];</span> <span class="n">titleBar</span><span class="p">.</span><span class="n">ButtonForegroundColor</span> <span class="p">=</span> <span class="n">Colors</span><span class="p">.</span><span class="n">White</span><span class="p">;</span> </code></pre> </div> <p>This gives me that best result for my app in my opinion, but will vary with the style and content of each app.</p> <p><a href="/content/images/posts/extend.png"><img width="600" src="/content/images/posts/extend.png" /></a></p> <h2 id="conclusion">Conclusion</h2> <p>Now that how apps are going to be in windows a lot of the time we need to pay more attention to things like the title bar.</p> Thu, 09 Apr 2015 00:00:00 +0000 http://compiledexperience.com/blog/posts/windows-10-title-bar http://compiledexperience.com/blog/posts/windows-10-title-bar nigel.sampson@compiledexperience.com (Nigel Sampson) What's new in Windows 10 - Http Live Streaming <p>Microsoft have finally started to show off what’s available in Windows 10 for us app developers. Over the next few days we can start to take a look at some of these changes and what it can mean. Today we’ll look at what’s available for media playback with <code class="highlighter-rouge">AdaptiveMediaSource</code>.</p> <h2 id="disclaimer">Disclaimer</h2> <p>This was written using the initial release of the Windows 10 Developer Tools running on Windows 10 build 10041 and things will mostly change before final release. I’ll try to come back and keep these posts up to date as time goes on.</p> <h2 id="http-live-streaming">HTTP Live Streaming</h2> <p>There are a lot of adaptive live video streaming formats out there. The three most popular are:</p> <ol> <li><a href="http://en.wikipedia.org/wiki/HTTP_Live_Streaming">HLS</a></li> <li><a href="http://en.wikipedia.org/wiki/Dynamic_Adaptive_Streaming_over_HTTP">MPEG-DASH</a></li> <li><a href="http://www.iis.net/downloads/microsoft/smooth-streaming">Smooth Streaming</a></li> </ol> <p>Previously if wanted to use HLS in our Windows 8 apps we needed to use a custom media source, some of the free ones available to download were worth the cost and the better ones were pretty pricey. For the latter two we could use <a href="https://playerframework.codeplex.com/">Player Framework</a>.</p> <p>If you’re doing any complex media scenarios I’d still recommend <a href="https://playerframework.codeplex.com/">Player Framework</a> but if you just want to display some HTTP Live Streaming content in your app then there’s a lot more in the box with <code class="highlighter-rouge">AdaptiveMediaSource</code>.</p> <p>To create an instance of <code class="highlighter-rouge">AdaptiveMediaSource</code> we use either <code class="highlighter-rouge">CreateFromStreamAsync</code> or <code class="highlighter-rouge">CreateFromUriAsync</code>.</p> <div class="highlighter-rouge"><pre class="highlight"><code><span class="n">var</span> <span class="n">hlsUri</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Uri</span><span class="p">(</span><span class="s">"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"</span><span class="p">);</span> <span class="n">var</span> <span class="n">hlsSource</span> <span class="p">=</span> <span class="n">await</span> <span class="n">AdaptiveMediaSource</span><span class="p">.</span><span class="nf">CreateFromUriAsync</span><span class="p">(</span><span class="n">hlsUri</span><span class="p">);</span> </code></pre> </div> <p>This returns a <code class="highlighter-rouge">AdaptiveMediaSourceCreationResult</code> which includes the source and whether the manifest was able to be downloaded or what error occurred.</p> <div class="highlighter-rouge"><pre class="highlight"><code><span class="nt">&lt;MediaElement</span> <span class="na">x:Name=</span><span class="s">"Media"</span> <span class="nt">/&gt;</span> </code></pre> </div> <div class="highlighter-rouge"><pre class="highlight"><code><span class="k">if</span> <span class="p">(</span><span class="n">hlsSource</span><span class="p">.</span><span class="n">Status</span> <span class="p">==</span> <span class="n">AdaptiveMediaSourceCreationStatus</span><span class="p">.</span><span class="n">Success</span><span class="p">)</span> <span class="n">Media</span><span class="p">.</span><span class="nf">SetMediaStreamSource</span><span class="p">(</span><span class="n">hlsSource</span><span class="p">.</span><span class="n">MediaSource</span><span class="p">);</span> </code></pre> </div> <p>One thing to remember is that you need the <code class="highlighter-rouge">internetClient</code> capability declared in your appxmanifest. Lost some time trying to diagnose a result of <code class="highlighter-rouge">AdaptiveMediaSourceCreationStatus.ManifestDownloadFailure</code>.</p> <div class="highlighter-rouge"><pre class="highlight"><code><span class="nt">&lt;Capabilities&gt;</span> <span class="nt">&lt;Capability</span> <span class="na">Name=</span><span class="s">"internetClient"</span> <span class="nt">/&gt;</span> <span class="nt">&lt;/Capabilities&gt;</span> </code></pre> </div> <h2 id="conclusion">Conclusion</h2> <p>Having this functionality in the box is going to make building any sort of app that is supported by video content a lot easier, can’t wait to get to using it.</p> Wed, 08 Apr 2015 00:00:00 +0000 http://compiledexperience.com/blog/posts/windows-10-live-streaming http://compiledexperience.com/blog/posts/windows-10-live-streaming nigel.sampson@compiledexperience.com (Nigel Sampson) What's new in Windows 10 - C# 6.0 <p>Microsoft have finally started to show off what’s available in Windows 10 for us app developers. Over the next few days we can start to take a look at some of these changes and what it can mean. Today we’ll look at what it means now we can develop with C# 6.</p> <h2 id="disclaimer">Disclaimer</h2> <p>This was written using the initial release of the Windows 10 Developer Tools running on Windows 10 build 10041 and things will mostly change before final release. I’ll try to come back and keep these posts up to date as time goes on.</p> <h2 id="c-6">C# 6</h2> <p>While this isn’t technically a Windows 10 feature it’s something that will kind of slip under the radar. When we build Windows 10 apps with Visual Studio 2015 we’ll have the C# 6 features available to us. There’s huge list of new features, and I don’t want to cover all of them just highlight a few that show up in Windows 10 / MVVM apps.</p> <h3 id="null-conditional-operators">Null conditional operators</h3> <p>The null conditional operator reduces the amount of code you’re going to need to write for null checking. Because the feature evaluates the left hand side of the <code class="highlighter-rouge">?.</code> only once it provides a thread safe way to invoke events like follows.</p> <div class="highlighter-rouge"><pre class="highlight"><code><span class="k">protected</span> <span class="k">void</span> <span class="nf">OnPropertyChanged</span><span class="p">(</span><span class="kt">string</span> <span class="n">propertyName</span><span class="p">)</span> <span class="p">{</span> <span class="n">PropertyChanged</span><span class="p">?.</span><span class="nf">Invoke</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="k">new</span> <span class="nf">PropertyChangedEventArgs</span><span class="p">(</span><span class="n">propertyName</span><span class="p">));</span> <span class="p">}</span> </code></pre> </div> <h3 id="nameof-operator">nameof operator</h3> <p>The <code class="highlighter-rouge">nameof</code> operator is a simple one that provides a a string that names a program element, obvious use cases are for things like <code class="highlighter-rouge">ArgumentNullException</code>. However property changed notifications are another, anything that means less strings in your code is a good thing in my books.</p> <div class="highlighter-rouge"><pre class="highlight"><code><span class="k">public</span> <span class="kt">string</span> <span class="n">Username</span> <span class="p">{</span> <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="n">username</span><span class="p">;</span> <span class="p">}</span> <span class="k">set</span> <span class="p">{</span> <span class="n">username</span> <span class="p">=</span> <span class="k">value</span><span class="p">;</span> <span class="nf">OnPropertyChanged</span><span class="p">(</span><span class="nf">nameof</span><span class="p">(</span><span class="n">Username</span><span class="p">));</span> <span class="p">}</span> <span class="p">}</span> </code></pre> </div> <h2 id="conclusion">Conclusion</h2> <p>There’s a lot of really cool features coming in C# 6, one of the best places to check them out is the the <a href="http://blogs.msdn.com/b/csharpfaq/archive/2014/11/20/new-features-in-c-6.aspx">C# team blog</a>. I’d suggest thinking about how they’ll affect your codebase and don’t forget you have them available to you when building Windows 10 apps.</p> Tue, 07 Apr 2015 00:00:00 +0000 http://compiledexperience.com/blog/posts/windows-10-c-sharp-6 http://compiledexperience.com/blog/posts/windows-10-c-sharp-6 nigel.sampson@compiledexperience.com (Nigel Sampson) What's new in Windows 10 - Key Accelerators <p>Microsoft have finally started to show off what’s available in Windows 10 for us app developers. Over the next few days we can start to take a look at some of these changes and what it can mean. Today we’ll look at what you can do with the <code class="highlighter-rouge">Windows.UI.Xaml.KeyAccelerator</code> class.</p> <h2 id="disclaimer">Disclaimer</h2> <p>This was written using the initial release of the Windows 10 Developer Tools running on Windows 10 build 10041 and things will mostly change before final release. I’ll try to come back and keep these posts up to date as time goes on.</p> <h2 id="key-accelerator">Key Accelerator</h2> <p>Keyboard shortcuts aren’t thought much about by app developers, we typically envisage our app running on a touch enabled tablet or phone. Although Windows 8 apps would run with no problems on desktop devices they weren’t thought of as a target. Windows 10 by supporting <em>Desktop Mode</em> and the <em>Continuum</em> feature should drive more usage of Windows Apps on the desktop. In these scenarios we as developers should think about keyboard shortcuts and how they can increase the productivity of their users.</p> <p>So Windows 10 adds the <code class="highlighter-rouge">Windows.UI.Xaml.KeyAccelerator</code> class which provides a way to declare keyboard shortcuts for a <code class="highlighter-rouge">Windows.UI.Xaml.Controls.Page</code> in your xaml as you can see below.</p> <div class="highlighter-rouge"><pre class="highlight"><code><span class="nt">&lt;Page.KeyAccelerators&gt;</span> <span class="nt">&lt;KeyAccelerator</span> <span class="na">Key=</span><span class="s">"N"</span> <span class="na">KeyModifiers=</span><span class="s">"Control"</span> <span class="na">Pressed=</span><span class="s">"OnNewProject"</span> <span class="nt">/&gt;</span> <span class="nt">&lt;/Page.KeyAccelerators&gt;</span> </code></pre> </div> <p>When that key combination is pressed (in this case Ctrl+N) then the <code class="highlighter-rouge">Pressed</code> event is invokes, it’s handler looks like the following.</p> <div class="highlighter-rouge"><pre class="highlight"><code><span class="k">private</span> <span class="k">void</span> <span class="nf">OnNewProject</span><span class="p">(</span><span class="n">KeyAccelerator</span> <span class="n">key</span><span class="p">,</span> <span class="kt">object</span> <span class="n">param</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span> </code></pre> </div> <h2 id="conclusion">Conclusion</h2> <p>Key Accelerators are a nice simple feature to implement. I’d suggest as an exercise working through each of your views and determining the major commands for each and assign them a keyboard shortcut.</p> Thu, 02 Apr 2015 00:00:00 +0000 http://compiledexperience.com/blog/posts/windows-10-keyaccelerators http://compiledexperience.com/blog/posts/windows-10-keyaccelerators nigel.sampson@compiledexperience.com (Nigel Sampson)