{"id":113,"date":"2014-06-20T07:00:00","date_gmt":"2014-06-20T15:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vbteam\/2014\/06\/20\/vb-universal-windows-app-part-5-calling-into-platform-specific-apis-from-pcl\/"},"modified":"2024-07-05T12:37:45","modified_gmt":"2024-07-05T19:37:45","slug":"vb-universal-windows-app-part-5-calling-into-platform-specific-apis-from-pcl","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/vbteam\/vb-universal-windows-app-part-5-calling-into-platform-specific-apis-from-pcl\/","title":{"rendered":"VB Universal Windows App Part 5: calling into platform-specific APIs from PCL"},"content":{"rendered":"<p>This is Part 5 of the &#8220;<a href=\"http:\/\/blogs.msdn.com\/b\/vbteam\/archive\/tags\/universal\/\">VB Universal Windows App<\/a>&#8221; series:<\/p>\n<ul>\n<li><a href=\"http:\/\/blogs.msdn.com\/b\/vbteam\/archive\/2014\/06\/15\/vb-universal-app-part-1-getting-started.aspx\">Part 1: Setting up the universal Windows app in the Dev Centers, and in VS Solution Explorer<\/a><\/li>\n<li><a href=\"http:\/\/blogs.msdn.com\/b\/vbteam\/archive\/2014\/06\/15\/vb-universal-app-part-2-for-the-developer-sharing-xaml-assets-and-code.aspx\">Part 2: Sharing XAML, Assets and Code<\/a><\/li>\n<li><a href=\"http:\/\/blogs.msdn.com\/b\/vbteam\/archive\/2014\/06\/15\/vb-universal-app-part-3-for-the-end-user-roaming-settings-and-in-app-purchases.aspx\">Part 3: Local and Roaming settings, and In-App purchases<\/a><\/li>\n<li><a href=\"http:\/\/blogs.msdn.com\/b\/vbteam\/archive\/2014\/06\/15\/vb-universal-app-part-4-using-sharpdx-for-sound-effects-with-ioc-and-linkedfiles.aspx\">Part 4: Sound effects with SharpDX<\/a><\/li>\n<li><span style=\"color: #000000\"><strong>&gt; Part 5: How to call platform-specific APIs from common code<\/strong><\/span><\/li>\n<li><span style=\"color: #000000\"><a href=\"http:\/\/blogs.msdn.com\/b\/vbteam\/archive\/2014\/06\/21\/vb-universal-app-downloads.aspx\">Download full source code<\/a><\/span><\/li>\n<\/ul>\n<p>So far we&#8217;ve been able to re-use all our code and XAML by placing them in the PCL. Actually, PCLs can only ever contain calls to APIs that are <em>common<\/em> to the platforms they target. This generally isn&#8217;t a problem, because most APIs on Windows also exist on Windows Phone, and vice versa.<\/p>\n<p>Today we&#8217;ll explore how to call <em>platform&#8211;specific<\/em> APIs from Common code. In particular, we&#8217;ll make it so our common main page can hide the Windows Phone statusbar (with connection quality, battery, clock) &#8211; when it&#8217;s running on Windows Phone, of course. There&#8217;s nothing that needs hiding on Windows.<\/p>\n<h2>Inversion of Control<\/h2>\n<p>We&#8217;ll use a technique known as &#8220;Inversion of Control&#8221; (IOC). It sounds complicated but is easy in practice. Advanced developers frequently use IOC for unit-testing as well.<\/p>\n<ul>\n<li><a href=\"http:\/\/media.ch9.ms\/ch9\/f2f3\/6fa5f5ac-2087-4d27-83f7-f90f0f63f2f3\/9ioc_Source.wmv\">How do I video: call platform-specific APIs from the PCL-based common code<\/a> [3mins]<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p><strong>Step 1:<\/strong> Declare a new interface &#8220;IPlatformAbstraction&#8221; in App1_Common &gt; App.vb, and a public field of that type.<\/p>\n<p style=\"margin-bottom: .0001pt;line-height: normal\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Public<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Interface<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">IPlatformAbstraction<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Function<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> SetStatusbarVisibilityAsync(isVisible <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Boolean<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">) <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Task<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Interface<\/p>\n<p> Public<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Class<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">App<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Public<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Shared<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> Platform <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">IPlatformAbstraction<br \/> <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; &#8230;.<\/span><br \/> <span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue\">End Class<\/p>\n<p> <\/span><\/p>\n<p><strong>Step 2:<\/strong> Any time you want to play audio from within App1_Common, do so via the platform abstraction layer:<\/p>\n<p style=\"margin-bottom: .0001pt;line-height: normal\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue\">Await <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">App<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Platform.SetStatusbarVisibilityAsync(<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">False<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">)<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>Step 3:<\/strong> Now you have to provide two implementations of the interface, one in App1_Windows, and one in App1_Phone. I chose to provide it inside my two App.xaml.vb files. Remember also to assign &#8220;App1_Common.App.Platform&#8221; inside the OnLaunched method.<\/p>\n<p style=\"margin-bottom: .0001pt;line-height: normal\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">NotInheritable<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Class<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">App<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Inherits<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Application<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Implements<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> App1_Common.<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">IPlatformAbstraction<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Public<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Async Function<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> SetStatusbarVisibilityAsync(isVisible <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As Boolean<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">) <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Implements<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">IPlatformAbstraction<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.SetStatusbarVisibilityAsync<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\">&#8216; TODO: implement this!<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Protected<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Overrides<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> OnLaunched(e <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">LaunchActivatedEventArgs<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">)<\/span>&lt;<br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; App1_Common.<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">App<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Platform = <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Me<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;.<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; &#8230;.<br \/> <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Class<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2>How to deal with status-bar visibility on Windows Phone<\/h2>\n<p>Look at these screenshots. (To test how my app behaves with &#8220;software-buttons&#8221; I launched either the 720p or 1080p emulators, clicked on &gt;&gt; then Sensors, and turned on software buttons).<\/p>\n<p><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: #2b91af;background: white\">ApplicationView<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">.GetForCurrentView().SetDesiredBoundsMode(<br \/> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: #2b91af;background: white\">ApplicationViewBoundsMode<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">.UseCoreWindow)<\/span><\/p>\n<p>The screenshot on the left used <strong>ApplicationViewBoundsMode.UseVisible<\/strong>. You can see that it calculated the layout rectangle of my page based only on what&#8217;s visible, after you take away the space for software-buttons and status-bar.<\/p>\n<p>The screenshot on the right used <strong>ApplicationViewBoundsMode.UseCoreWindow<\/strong>. You can see that it calculated the layout rectangle of my page based on the full screen size, regardless of software-buttons and status-bar.<\/p>\n<table style=\"border: currentColor;border-collapse: collapse\" border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td style=\"padding: 0in 5.4pt;border: 1pt solid windowtext;width: 233.75pt\" valign=\"top\" width=\"468\">\n<p style=\"line-height: normal;margin-bottom: 0pt\"><a href=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2014\/06\/1856.statusbar_1.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2014\/06\/1856.statusbar_1.png\" alt=\"\" border=\"0\" \/><\/a><\/p>\n<\/td>\n<td style=\"border-width: 1pt 1pt 1pt medium;border-style: solid solid solid none;border-color: windowtext windowtext windowtext currentColor;padding: 0in 5.4pt;width: 233.75pt\" valign=\"top\" width=\"468\">\n<p style=\"line-height: normal;margin-bottom: 0pt\">&nbsp;<a href=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2014\/06\/2313.statusbar_3.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2014\/06\/2313.statusbar_3.png\" alt=\"\" border=\"0\" \/><\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p>The status-bar visibility (at the top) is under the app&#8217;s control. The app can show or hide it. Showing and hiding takes about half a second, since it&#8217;s accompanied by a nice animation. These are the two methods you can use:<\/p>\n<p style=\"margin-bottom: .0001pt;line-height: normal\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Await<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">StatusBar<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.GetForCurrentView().ShowAsync()<br \/> &nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Await<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">StatusBar<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.GetForCurrentView().HideAsync()<\/span><\/p>\n<p>&nbsp;<\/p>\n<p>The software-button visibility (at the bottom) is under the user&#8217;s control. And most phones come with hardware buttons, not software buttons, so they don&#8217;t even show these.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Step 4:<\/strong> Implement the SetStatusbarVisibility method of our Platform Abstraction Layer:<\/p>\n<p style=\"margin-bottom: .0001pt;line-height: normal\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"><br \/> &nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\">&#8216; PHONE IMPLEMENTATION, in App1_Phone &gt; App.xaml.vb<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Public<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Async Function<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> SetStatusbarVisibilityAsync(isVisible <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As Boolean<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">) <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Implements<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">IPlatformAbstraction<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.SetStatusbarVisibilityAsync<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">If<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> isVisible <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Then<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Await<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">StatusBar<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.GetForCurrentView().ShowAsync()<\/span>&gt;br\/&gt; <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Else<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Await<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">StatusBar<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.GetForCurrentView().HideAsync()<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">If<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"><br \/> &nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span><\/p>\n<p> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\">&#8216; WINDOWS VERSION, in App1_Windows &gt; App.xaml.vb<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Public<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Async Function<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> SetStatusbarVisibilityAsync(isVisible <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As Boolean<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">) <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Implements<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">IPlatformAbstraction<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.SetStatusbarVisibilityAsync<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">If<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">False<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Then<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Await<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Task<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.Delay(0) <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: green;background: white\">&#8216; dummy to silence the compiler warning<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"><br \/> &nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2>Fire-and-forget async methods<\/h2>\n<p>There&#8217;s one final tweak I want to mention. It&#8217;s inside App1_Common &gt; AdaptiveMainPage.xaml.vb &gt; OnNavigatedTo that I want to call SetStatusbarVisibilityAsync.<\/p>\n<p>But hiding the statusbar has a half-second animation, and I don&#8217;t want to delay my OnNavigatedTo method while waiting for it to finish. In effect, I want to just kick off the async method in a <em>fire-and-forget<\/em> manner.<\/p>\n<p>Here is a nice idiom for fire-and-forget asyncs. It uses an extension method &#8220;FireAndForget&#8221; which I wrote. It silences the compiler warning (&#8220;hey you&#8217;re not awaiting this async method&#8221;). And it demonstrates to anyone reading my code what I&#8217;m trying to do:<\/p>\n<p><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: #2b91af;background: white\">App<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">.Platform.SetStatusbarVisibilityAsync(<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">False<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">).FireAndForget()<\/span><\/p>\n<p>And here&#8217;s how I implement that FireAndForget extension method:<\/p>\n<p style=\"margin-bottom: .0001pt;line-height: normal\"><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Module<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">AsyncHelpers<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; &lt;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Extension<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&gt; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Async<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Sub<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> FireAndForget(task <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Task<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">)<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Try<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Await<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> task<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Catch<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\"> ex <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">As<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">Exception<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: #2b91af;background: white\">App<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">.SendErrorReport(ex)<\/span><br \/> <span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">End<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;font-family: Consolas;color: blue;background: white\">Try<\/span><br \/> <span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; <\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">End<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">Sub<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue\"><br \/> <span style=\"background: white\">End<\/span><\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">Module<\/span><\/p>\n<p>Actually, in practice, I also often write two additional FireAndForget overloads, to make it easy to use with asynchronous WinRT APIs. They&#8217;re implemented exactly the same way:<\/p>\n<p><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">&nbsp;&nbsp;&nbsp; &lt;<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: #2b91af;background: white\">Extension<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">&gt; <\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">Async<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">Sub<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\"> FireAndForget(task <\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">As<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: #2b91af;background: white\">IAsyncAction<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">)<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black\"><br \/> <span style=\"background: white\">&nbsp;&nbsp;&nbsp; &lt;<\/span><\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: #2b91af;background: white\">Extension<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">&gt; <\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">Async<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">Sub<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\"> FireAndForget(<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">Of<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: #2b91af;background: white\">T<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">)(task <\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">As<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: #2b91af;background: white\">IAsyncOperation<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">(<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: blue;background: white\">Of<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">&nbsp;<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: #2b91af;background: white\">T<\/span><span style=\"font-size: 9.5pt;line-height: 107%;font-family: Consolas;color: black;background: white\">))<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2>Conclusion<\/h2>\n<p>We&#8217;ve now created a complete VB Universal app &#8211; although under the hood, a universal app is really two separate apps. In this blog series we&#8217;ve used two techniques for sharing code between the two apps. We&#8217;ve been able to share most of our code, XAML and assets by putting them inside a PortableClassLibrary. And we&#8217;ve used Inversion Of Control (IOC) to let the PCL call into platform-specific APIs.<\/p>\n<p>Good luck, as you go out and build your own VB Universal Apps! It&#8217;s an open app-store out there, ready for you to make your impact.<\/p>\n<p>And stay tuned for tomorrow&#8217;s blog post, with complete source code for the minimal &#8220;App1.vb&#8221; that we&#8217;ve been creating so far, and also complete source code for a fully-fledged universal VB game &#8220;Breakout Universal&#8221;.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is Part 5 of the &#8220;VB Universal Windows App&#8221; series: Part 1: Setting up the universal Windows app in the Dev Centers, and in VS Solution Explorer Part 2: Sharing XAML, Assets and Code Part 3: Local and Roaming settings, and In-App purchases Part 4: Sound effects with SharpDX &gt; Part 5: How to [&hellip;]<\/p>\n","protected":false},"author":260,"featured_media":8818,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[16,195],"tags":[36,99,160,180],"class_list":["post-113","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-vb-universal-windows-apps","category-visual-basic","tag-async","tag-lucian-wischik","tag-universal","tag-windows-phone"],"acf":[],"blog_post_summary":"<p>This is Part 5 of the &#8220;VB Universal Windows App&#8221; series: Part 1: Setting up the universal Windows app in the Dev Centers, and in VS Solution Explorer Part 2: Sharing XAML, Assets and Code Part 3: Local and Roaming settings, and In-App purchases Part 4: Sound effects with SharpDX &gt; Part 5: How to [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/113","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/users\/260"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/comments?post=113"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/113\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media\/8818"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media?parent=113"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/categories?post=113"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/tags?post=113"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}