<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>The UX Blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/theuxblog/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/theuxblog/feed.xml</link>
    <description>User Experience in Microsoft Services</description>
    <lastBuildDate>Tue, 16 Apr 2019 05:32:22 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Integrating desktop code into UWP apps with an AppService</title>
      <link>https://docs.microsoft.com/archive/blogs/theuxblog/integrating-desktop-code-into-uwp-apps</link>
      <pubDate>Wed, 22 Nov 2017 16:02:01 GMT</pubDate>
      <dc:creator><![CDATA[ptallett]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/theuxblog/?p=256</guid>
      <description><![CDATA[UWP apps are great, with a clean install experience and buttery smooth touch. But what if you want...]]></description>
      <content:encoded><![CDATA[UWP apps are great, with a clean install experience and buttery smooth touch. But what if you want to call desktop DLLs or break out of the sandbox and call desktop APIs?

You may have heard of Brokered Components that used COM wrappers to call into Win32 code, but these were quite messy to deploy, and required a certain amount of COM/C++ knowledge which if you are old enough to remember, you have probably forgotten the details. Also, because this technology required external components, registry settings and unsigned code, you couldn't use this method in apps submitted to the Store.

With Windows 10 Anniversary Update (14393, RS1, 1607) there's a new feature, the FullTrustProcessLauncher. You've probably heard of AppServices where an app can expose functionality to other apps, but did you know you can have a Win32 (eg WPF) child process and communicate with it over an AppService and bundle it as part of your AppX so it cleanly installs with your app. So imagine you have a desktop project implementing your Win32 logic and a UWP project targetting 14393 or better. You can just create a subfolder (say "Win32App") in the UWP project, and create links to your Win32App EXE and any dependant DLLs and set the build action to "copy to output". This will bundle your Win32App into your AppX and deploy it to a subdirectory called "Win32App". (Note it has to be a subfolder, it doesn't seem to work if you put the EXE in the root folder). Then your UWP can expose an AppService that the Win32App can connect to and communicate with your UWP.

Then some stuff in your manifest:

Some more namespaces:

&lt;Package xmlns="https://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="https://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="https://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="https://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" xmlns:desktop="https://schemas.microsoft.com/appx/manifest/desktop/windows10" IgnorableNamespaces="uap mp rescap desktop"&gt;

...

&lt;Extensions&gt;
&lt;desktop:Extension Category="windows.fullTrustProcess" Executable=" Win32App\Win32App.exe" /&gt;
&lt;/Extensions&gt;

...

&lt;Capabilities&gt;
&lt;rescap:Capability Name="runFullTrust" /&gt;
&lt;/Capabilities&gt;

Then your code calls

await Windows.ApplicationModel.FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();

which starts your Win32 process. The Win32 process then connects to your AppService and you can communicate with it:

ValueSet valueSet = new ValueSet();
valueSet.Add("stuff", "args");

if (App.Connection != null)
{
AppServiceResponse response = await App.Connection.SendMessageAsync(valueSet);
if (response?.Message != null)
...

All the communication is built into the platform! Super slick. You need to get a full trust waiver to submit apps using this technology to the Store, not sure how easy that is, but the cool thing is because your Win32App is part of your AppX, it gets signed as part of the Store process so your app even works on Windows 10S! Note the FullTrustProcessLauncher is in the desktop extension SDK. Also note that your Win32App has identity so it can call Modern APIs such as accessing the UWP's temp storage. Use the following to add Modern references to your Win32App  <a href="https://blogs.msdn.microsoft.com/lucian/2015/10/23/how-to-call-uwp-apis-from-a-desktop-vbc-app">https://blogs.msdn.microsoft.com/lucian/2015/10/23/how-to-call-uwp-apis-from-a-desktop-vbc-app</a> (NuGet UWPDesktop)

Also when submitting your app to the Store, if you use the standard .appxupload file you get an error. The workaround is to drill into your package folder and zip the appxbundle and the appxsym into a zip file and call it .appxupload and then upload that. Seems to get around it.

Anyway, this article was just to get you familiar with the process, there's a couple more details and bits of code you need so head right over to the SDK sample and give it a shot.

<a href="https://github.com/Microsoft/DesktopBridgeToUWP-Samples/tree/master/Samples/AppServiceBridgeSample">https://github.com/Microsoft/DesktopBridgeToUWP-Samples/tree/master/Samples/AppServiceBridgeSample</a>

Enjoy!

<strong>Paul Tallett, App Dev Architect, UX Global Practice, Microsoft, November 2017</strong>

<strong>Disclaimer: The information on this site is provided AS IS with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the </strong><a href="https://www.microsoft.com/en-us/legal/intellectualproperty/copyright">Terms of Use</a>.

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Variable height expand/collapse rows in a ListView with HasUnevenRows in Xamarin Forms</title>
      <link>https://docs.microsoft.com/archive/blogs/theuxblog/variable-height-expandcollapse-rows-in-a-listview-with-hasunevenrows-in-xamarin-forms</link>
      <pubDate>Tue, 04 Jul 2017 09:34:30 GMT</pubDate>
      <dc:creator><![CDATA[ptallett]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/theuxblog/?p=225</guid>
      <description><![CDATA[Hi!

Recently I was asked to make a ListView in Xamarin Forms (on iOS at the moment) where you...]]></description>
      <content:encoded><![CDATA[Hi!

Recently I was asked to make a ListView in Xamarin Forms (on iOS at the moment) where you could expand and collapse rows by clicking on them. This is quite a common paradigm but is actually quite hard to do in Xamarin Forms. The problem is, the ListView doesn't re-layout the items when you expand and collapse them, so they overlap and it looks horrible. Here's my ListView:
<pre>&lt;ListView x:Name="listView" ItemsSource="{Binding List, Mode=OneWay}" HasUnevenRows="True" SeparatorVisibility="None" Grid.Row="3"&gt;
  &lt;ListView.ItemTemplate&gt;
    &lt;DataTemplate&gt;
       &lt;ViewCell&gt;
         &lt;StackLayout Orientation="Vertical"&gt;
             &lt;Grid ColumnSpacing="0" RowSpacing="0" BackgroundColor="White" Margin="10,0" Padding="10"&gt;
               &lt;Grid.RowDefinitions&gt;
                 &lt;RowDefinition Height="Auto"/&gt;
                   &lt;RowDefinition Height="Auto"/&gt;
                   &lt;RowDefinition Height="Auto"/&gt;
                 &lt;/Grid.RowDefinitions&gt;
                 &lt;Grid.ColumnDefinitions&gt;
                   &lt;ColumnDefinition Width="*"/&gt;
                   &lt;ColumnDefinition Width="*"/&gt;
                   &lt;ColumnDefinition Width="*"/&gt;
                   &lt;ColumnDefinition Width="30"/&gt;
                 &lt;/Grid.ColumnDefinitions&gt;
                 &lt;Grid.GestureRecognizers&gt;
                   &lt;TapGestureRecognizer Command="{Binding BindingContext.ExpandCommand, Source={x:Reference thisPage}}" CommandParameter="{Binding .}"/&gt;
                 &lt;/Grid.GestureRecognizers&gt;
                 &lt;Label Grid.Row="0" Grid.Column="0" Text="{Binding Name}"/&gt;
                 &lt;Label Grid.Row="0" Grid.Column="1" Text="{Binding Created}"/&gt;
                 &lt;StackLayout Grid.Row="0" Grid.Column="3" HorizontalOptions="End" VerticalOptions="Start" Margin="0,0,10,0" WidthRequest="20" HeightRequest="20"&gt;
                   &lt;Image Source="{Binding IsExpanded, Converter={StaticResource BoolToStringConverter}, ConverterParameter='chevronup.png:chevrondown.png'}" WidthRequest="20" HeightRequest="20"/&gt;
                 &lt;/StackLayout&gt;
                 &lt;Label Grid.Row="1" Grid.Column="1" Text="Style" HorizontalOptions="Start" /&gt;
                 &lt;Label Grid.Row="1" Grid.Column="2" Text="{Binding Style}" HorizontalOptions="Start"/&gt;
                 &lt;Grid Grid.Row="2" ColumnSpacing="0" RowSpacing="0" BackgroundColor="White" Margin="0,10,0,0" Grid.ColumnSpan="4" HorizontalOptions="Start" IsVisible="{Binding IsExpanded}"&gt;
                   &lt;Grid.RowDefinitions&gt;
                     &lt;RowDefinition Height="Auto"/&gt;
                     &lt;RowDefinition Height="Auto"/&gt;
                   &lt;/Grid.RowDefinitions&gt;
                   &lt;Grid.ColumnDefinitions&gt;
                     &lt;ColumnDefinition Width="*"/&gt;
                     &lt;ColumnDefinition Width="*"/&gt;
                     &lt;ColumnDefinition Width="*"/&gt;
                     &lt;ColumnDefinition Width="30"/&gt;
                   &lt;/Grid.ColumnDefinitions&gt;
                   &lt;StackLayout Orientation="Horizontal" Grid.Row="2" Grid.Column="1"&gt;
                     &lt;Label Text="Weight" /&gt;
                     &lt;Label Text="{Binding Weight}" /&gt;
                   &lt;/StackLayout&gt;
                   &lt;Label Grid.Row="2" Grid.Column="2" Text="{Binding ActualWeight}" /&gt;
                 &lt;/Grid&gt;
               &lt;/Grid&gt;
             &lt;/StackLayout&gt;
           &lt;/ViewCell&gt;
         &lt;/DataTemplate&gt;
       &lt;/ListView.ItemTemplate&gt;
     &lt;/ListView&gt;</pre>
Now setting the IsExpanded flag on the item will expand the second Grid, but it overlaps the items below it. I read somewhere that the ListView only does layout when the ItemsSource changes, so I first tried setting the ItemsSource to null, waiting for 50 msecs, then setting it back to its original value. This worked okay although the UI flashed a bit, and I thought I was home and dry. Then I tried a list that had a lot of items and realised that the scroll view position was getting reset to the top. I then monkeyed around with scrolling the ListView back to where it should be but it was all pretty ugly.

Then I found someone who was trying to do the opposite to me - he was trying to set the scroll position to the top when he loaded new items in the list, and I realised that the scroll view must not move when you reset the ItemsSource. So here's my final solution:
<pre>ExpandCommand = new DelegateCommand&lt;ListItem&gt;(DoExpand);

       private void DoExpand(ListItem obj)
        {
            var data = new List&lt;ListItem&gt;(this.List);
            var expanded = obj.IsExpanded;
            foreach (var item in data)
                item.IsExpanded = false;
            obj.IsExpanded = !expanded;
            this.List = data;
        }</pre>
We change the ItemsSource to a collection that contains exactly the same items, but with some expanded or collapsed. The ListView dutifully re-lays out the items and recalculates the heights, but the scroll view stays in the same place (another bug in my opinion).

Works a treat! The items expand and collapse in place with hardly any flickering.

Enjoy!

<strong>Paul Tallett, App Dev Architect, UX Global Practice, Microsoft, July 2017</strong>
<div class="site container-fluid" id="page">
<div class="site-content row" id="site-content">
<div class="content-area col-sm-9" id="primary">
<div class="div-content" id="single-content"><article class="post-185 post type-post status-publish format-standard hentry category-uncategorized" id="post-185">
<div class="entry-content single">

<strong><span lang="EN-US">Disclaimer: The information on this site is provided AS IS with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the </span></strong><span lang="EN-US"><a href="https://www.microsoft.com/en-us/legal/intellectualproperty/copyright"><span>Terms of Use</span></a>.</span>

</div>
</article></div>
</div>
</div>
</div>
&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Display PDF document from WPF/Desktop app on Windows 10</title>
      <link>https://docs.microsoft.com/archive/blogs/theuxblog/display-pdf-document-from-wpfdesktop-app-on-windows-10</link>
      <pubDate>Sun, 11 Jun 2017 23:32:21 GMT</pubDate>
      <dc:creator><![CDATA[ptallett]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/theuxblog/?p=215</guid>
      <description><![CDATA[Hi!

There are many PDF libraries out there for displaying PDF documents (some very expensive,...]]></description>
      <content:encoded><![CDATA[Hi!

There are many PDF libraries out there for displaying PDF documents (some very expensive, personally I prefer Xfinium), but Windows 10 and .NET have built in classes for this. You can't do much except display a bitmap of the pages but this is often all you need. Here's how to do it from a WPF app.

// Call UWP APIs from
// <a href="https://blogs.msdn.microsoft.com/lucian/2015/10/23/how-to-call-uwp-apis-from-a-desktop-vbc-app">https://blogs.msdn.microsoft.com/lucian/2015/10/23/how-to-call-uwp-apis-from-a-desktop-vbc-app</a> (NuGet UWPDesktop)

// AsRandomAccessStream from
// <a href="https://stackoverflow.com/questions/7669311/is-there-a-way-to-convert-a-system-io-stream-to-a-windows-storage-streams-irando">https://stackoverflow.com/questions/7669311/is-there-a-way-to-convert-a-system-io-stream-to-a-windows-storage-streams-irando</a>

private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
using (var stream = File.OpenRead(@"x.pdf"))

{
var doc = await PdfDocument.LoadFromStreamAsync(stream.AsRandomAccessStream());
var page = doc.GetPage(0);
using (var mem = new MemoryStream())
{
await page.RenderToStreamAsync(mem.AsRandomAccessStream());
var bitmap = BitmapFrame.Create(mem, BitmapCreateOptions.IgnoreImageCache, BitmapCacheOption.OnLoad);
image.Source = bitmap;
}
}
}

Enjoy!
Paul Tallett, UX Global Practice, Microsoft UK

<!-- Begin Custom CSS --><!-- End Custom CSS -->
<div class="site container-fluid" id="page">
<div class="site-content row" id="site-content">
<div class="content-area col-sm-9" id="primary">
<div class="div-content" id="single-content"><article class="post-175 post type-post status-publish format-standard hentry category-uncategorized" id="post-175">
<div class="entry-content single">

<strong><span lang="EN-US">Disclaimer: The information on this site is provided AS IS with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the </span></strong><span lang="EN-US"><a href="https://www.microsoft.com/en-us/legal/intellectualproperty/copyright"><span>Terms of Use</span></a>.</span>

</div>
</article></div>
</div>
</div>
</div>
&nbsp;

&nbsp;

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Xamarin Tips and Tricks</title>
      <link>https://docs.microsoft.com/archive/blogs/theuxblog/xamarin-tips-and-tricks</link>
      <pubDate>Wed, 08 Feb 2017 09:05:09 GMT</pubDate>
      <dc:creator><![CDATA[ptallett]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/theuxblog/?p=185</guid>
      <description><![CDATA[Xamarin Tips and Tricks

In this blog post I’ll cover some of the basics of getting started with...]]></description>
      <content:encoded><![CDATA[<strong>Xamarin Tips and Tricks</strong>

In this blog post I’ll cover some of the basics of getting started with Xamarin along with some more advanced features. I’ll also cover common problems that you will doubtless encounter when developing with Xamarin.

<strong>Installing Xamarin</strong>

The Xamarin install is now included in Visual Studio 2015 (VS), so make sure you select it when installing VS. If you already have VS, then you can just download Xamarin from Xamarin.com and install it over the top. Try building an empty project and running it to check your install. On the MAC install from Xamarin.com and install Xamarin Studio and both the Android and iOS development environments. Don’t think you will not need to build Android on the MAC, sometimes you do.

<strong>Connecting to the MAC</strong>

One of the biggest hassles of doing iOS development is the need for a MAC to do development. The connection to the MAC is unreliable and sometimes doesn’t connect, even though it has connected before. Try removing your connection and adding it as an IP address (192.168.1.206). Also make sure you are using your short username (ptallett, not Paul Tallett) for the MAC. If you are still having troubles try restarting VS and rebooting both machines. Download an SSH client and check you can SSH from your Windows machine to the MAC (Xamarin uses an SSH connection). Also make sure you have compatible Xamarin versions on both machines. If you update Xamarin on Windows you will probably need to update the MAC before it will connect. There’s a troubleshooting guide here <a href="https://developer.xamarin.com/guides/ios/getting_started/installation/windows/connecting-to-mac/troubleshooting/">https://developer.xamarin.com/guides/ios/getting_started/installation/windows/connecting-to-mac/troubleshooting/</a>

<strong>Remote Simulator</strong>

You probably want VNC to remote into your MAC from Windows, but a neat addon for VS is the remoting tool for the iOS simulator. It remotes the UI for the simulator onto your Windows machine so you don’t have to deal with OSX so much.

<a href="https://developer.xamarin.com/guides/cross-platform/windows/ios-simulator/">https://developer.xamarin.com/guides/cross-platform/windows/ios-simulator/</a>

If it hangs when you first start it checking for updates, just kill it and run your project again. It should be fine then. I find this a really helpful tool.

<strong>Xamarin Versions</strong>

Its always worth going with the latest versions of everything, usually including NuGet packages as the general quality of the available code is somewhat buggy. Even pre-release can often help you. Upgrading Xamarin versions is somewhat painful so don’t fix it unless its broke, but be aware that you should always try to be on the latest versions when you have some breathing space.

<strong>NuGet is your friend</strong>

The NuGet integration in Visual Studio is really nice and is the preferred way to incorporate other libraries in your code. Visual Studio Source Control tends to add the contents of the packages folder into your repository, but you don’t really need it.

<strong>Xamarin Studio</strong>

Xamarin Studio on the MAC uses the same project file structure as VS and on occasion you may need to build your project on the MAC (see Native Code later).

<strong>Choice of frameworks</strong>

We use the PRISM navigation framework on our projects and it seems to work very well.

SkiaSharp is a Xamarin produced wrapper for the Google Skia graphics library and worked well for us.

HockeyApp has telemetry and app distribution which has been good for us.

NewtonSoft JSON is one of the most downloaded NuGet packages.

<strong>Xamarin Forms or Xamarin Native</strong>

Xamarin Forms has come a long way in the past 12 months and can now be used for quite complex projects. It is said that you need to go native if you have a lot of animations to do, but we found with SkiaSharp we were able to create quite complex cross-platform animations.

<strong>PCL or Shared Library</strong>

When you create your project you get the choice of a PCL (Portable Class Library) or Shared Library for your no-platform specific code. PCL is the older variant and if you have had experience of PCL’s on Windows, you may think they are quite restrictive and go for Shared Libraries. However, PCL is the way to go as they are not that restrictive (they have the full Mono .NET APIs), all the examples and code on the web seems to be PCL, and with Shared Libraries you can’t add references.

<strong>Platform Specific code</strong>

For platform specific code, create interfaces in your PCL and implement those interfaces in each of your platform specific projects. We used the Xamarin Forms dependency injection which worked well for us, so in the PCL you would write

DependencyService.Get&lt;IAudioEffects&gt;().PlaySoundOverBluetooth("HurryUpSound.wav");

<strong>Peculiar build problems</strong>

Often you may get compiler errors or linking/runtime errors which don’t make sense. That’s probably because they don’t. Exit out of VS, delete all your obj and bin folders, delete your packages folder and then do a Rebuild All.

<strong>MVVM</strong>

MVVM seems to be a popular pattern and is supported by Xamarin Forms with data binding and Command properties. Use the PRISM ViewModelLocator to wire up your View Models automatically in markup.

<strong>Displaying an image</strong>

Although this sounds like a trivial task, there are many different aspects regarding image display. Actually we realised during one project, that displaying images at all is actually a bad idea, and we switched over to using all SVG (Scalable Vector Graphics) images. These are much smaller, don’t require multiple resolutions as they scale, and are much crisper on high definition devices. To draw SVG images, we used SkiaSharp. We will cover displaying SVG images in another post, but if you really want to display PNG images, here’s some tips.

If you are developing for iOS and Android, you need to put copies of the images at different resolutions in both the iOS and Android projects, not your shared PCL. Android has some really fast methods for drawing images, but they only work on AndroidResources not stuff in your PCL. The paths to your images is different on both Android and iOS so we wrote a helper class to do the mappings (IMarkupExtension).

On Android, the Resources folder has subfolders called drawable, drawable-hdpi, drawable-xhdpi etc). You need to put your images in those folders (as AndroidResource’s) and create larger resolution images for the higher density displays. See <a href="https://developer.android.com/guide/topics/resources/providing-resources.html">https://developer.android.com/guide/topics/resources/providing-resources.html</a>

On iOS, the Resources folder contains the images (as BundleResources) at different resolutions directly, eg icon.png, icon@2x.png, icon@3x.png. Note that the scale factors for iOS are different to Android.

Don’t try and put a subfolder structure into your Resources folders. They are largely ignored and just confuse developers.

If you are trying to get the path to your resources, temporarily call the LIST methods to list the resources so you can see where they are and what the path is to the resources.

Generally using images uses up a lot of memory and really should be avoided.

<strong>Xamarin Forms</strong>

If you are familiar with XAML on Windows, you will find Xamarin Forms quite limited, but there is enough to get by.

Windows XAML                                                 Xamarin Forms

TextBlock                                                            Label
TextBox                                                               Entry
Grid                                                                     Grid
StackPanel                                                          StackLayout
ProgressRing                                                      ActivityIndicator
CheckBox                                                            No equivalent
Image                                                                  Image
Tapped event                                                      GestureRecognizer
SplitView                                                             MasterDetail page
ComboBox                                                          Picker (there’s a BindablePicker on the web)
Ellipse, Rectangle etc                                          No equivalent (use SVG or custom renderers)

&nbsp;

To use App.xaml see <a href="https://blogs.msdn.microsoft.com/devfish/2016/06/24/global-resources-in-xamarin-forms-no-app-xaml-create-one/">https://blogs.msdn.microsoft.com/devfish/2016/06/24/global-resources-in-xamarin-forms-no-app-xaml-create-one/</a>

Be careful with App.xaml though, creating a lot of global Styles can use up a lot of memory. Might be better to create your Styles in code.

<strong>Native Code</strong>

Calling native code (Java/Objective-C) is possible in Xamarin but I’ve found it quite tricky. Here’s some pointers:

<a href="https://blogs.msdn.microsoft.com/vcblog/2015/02/23/developing-xamarin-android-native-applications/">https://blogs.msdn.microsoft.com/vcblog/2015/02/23/developing-xamarin-android-native-applications/</a> <a href="https://jonathanpeppers.com/Blog/xamarin-ios-under-the-hood-calling-objective-c-from-csharp">https://jonathanpeppers.com/Blog/xamarin-ios-under-the-hood-calling-objective-c-from-csharp</a>

Note you can't build a native binding for iOS native code from Visual Studio, you have to do it in Xamarin Studio.

<a href="https://forums.xamarin.com/discussion/comment/5371#Comment_5371">https://forums.xamarin.com/discussion/comment/5371#Comment_5371</a>

<strong>Setting your application badge</strong>

iOS supports badges on your app icon natively, Android does not but most vendors have added this functionality in their extensions.

The Xam.Plugin.Badge NuGet package handles all this, but you need to make sure you have the permissions in your Android manifest:

&lt;!-- For Android --&gt;

&lt;uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" /&gt;
&lt;uses-permission android:name="com.android.launcher.permission.WRITE_SETTINGS" /&gt;
&lt;uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" /&gt;
&lt;uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" /&gt;
&lt;!--for Samsung--&gt;
&lt;uses-permission android:name="com.sec.android.provider.badge.permission.READ" /&gt;
&lt;uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" /&gt;
&lt;!--for htc--&gt;
&lt;uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS" /&gt;
&lt;uses-permission android:name="com.htc.launcher.permission.UPDATE_SHORTCUT" /&gt;
&lt;!--for sony--&gt;
&lt;uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE" /&gt;
&lt;uses-permission android:name="com.sonymobile.home.permission.PROVIDER_INSERT_BADGE" /&gt;
&lt;!--for apex--&gt;
&lt;uses-permission android:name="com.anddoes.launcher.permission.UPDATE_COUNT" /&gt;
&lt;!--for solid--&gt;
&lt;uses-permission android:name="com.majeur.launcher.permission.UPDATE_BADGE" /&gt;
&lt;!--for huawei--&gt;
&lt;uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE" /&gt;
&lt;uses-permission android:name="com.huawei.android.launcher.permission.READ_SETTINGS" /&gt;
&lt;uses-permission android:name="com.huawei.android.launcher.permission.WRITE_SETTINGS" /&gt;
&lt;!--for ZUK--&gt;
&lt;uses-permission android:name="android.permission.READ_APP_BADGE" /&gt;
&lt;!--for OPPO--&gt;
&lt;uses-permission android:name="com.oppo.launcher.permission.READ_SETTINGS" /&gt;
&lt;uses-permission android:name="com.oppo.launcher.permission.WRITE_SETTINGS" /&gt;

Or request badge permissions on iOS

var settings = UIUserNotificationSettings.GetSettingsForTypes(UIUserNotificationType.Badge, new NSSet());

UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);

<strong>Internationalisation</strong>

If you want to build apps that support multiple spoken languages (eg English, German, French) then the Multilingual App Toolkit supports Xamarin projects now and is brilliant for managing all the resource strings.

<strong>How do I bind to a command in a ListView</strong>

In a ListView ItemTemplate, your BindingContext is your data item, but you probably want gestures that bind to your ViewModel. You can use x:Static to reference your View, then BindingContext to get to your ViewModel:

&lt;ListView x:Name="CaptureListView" ItemsSource="{Binding Captures}"&gt;
&lt;ListView.ItemTemplate&gt;
&lt;DataTemplate&gt;
&lt;ViewCell&gt;
&lt;!-- Red grid for Delete command --&gt;
&lt;Grid x:Name="BackGrid" BackgroundColor="Red"&gt;
&lt;Grid.GestureRecognizers&gt;
&lt;TapGestureRecognizer Command="{Binding Path=BindingContext.DeleteCaptureCommand, Source={x:Reference HomePage}}" CommandParameter="{Binding}" /&gt;
&lt;/Grid.GestureRecognizers&gt;

&nbsp;

<strong>Navigation</strong>

Avoid creating loops in your navigation scheme which constantly push new copies of your View and ViewModel onto the back stack. Your users will very quickly run out of memory. Consider using back navigation to get back to the previous page rather than navigating to a new instance.

<strong>Custom Fonts</strong>

Xamarin now supports custom fonts out of the box, but the ways to invoke it are different on iOS and Android. Consider using

&lt;OnPlatform x:Key="FontVWTextWebBold" x:TypeArguments="x:String" iOS="VWTextWeb" Android="Fonts/VWTextWeb-Bold.ttf#VWTextWeb"/&gt;

Then set the FontFamily property.

&nbsp;

&nbsp;

<strong>I hope this helps you! Happy developing!</strong>

<strong>Paul Tallett, App Dev Architect, UX Global Practice, Microsoft, February 2017</strong>

<strong><span lang="EN-US">Disclaimer: The information on this site is provided “AS IS” with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the </span></strong><span lang="EN-US"><a href="https://www.microsoft.com/en-us/legal/intellectualproperty/copyright"><span>Terms of Use</span></a>.</span>

<span lang="EN-US"> </span>

&nbsp;]]></content:encoded>
    </item>
    <item>
      <title>Using the Microsoft OCR Library for WinRT from a desktop app</title>
      <link>https://docs.microsoft.com/archive/blogs/theuxblog/using-the-microsoft-ocr-library-for-winrt-from-a-desktop-app</link>
      <pubDate>Thu, 13 Oct 2016 13:04:53 GMT</pubDate>
      <dc:creator><![CDATA[ptallett]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/theuxblog/?p=175</guid>
      <description><![CDATA[Recently I had a need to do some OCR processing from a desktop app. Unfortunately the OCR package...]]></description>
      <content:encoded><![CDATA[<span style="color: #000000;font-family: Calibri">Recently I had a need to do some OCR processing from a desktop app. Unfortunately the OCR package from Microsoft is for WinRT apps only. However, by using this excellent NuGet package: </span><a href="https://blogs.msdn.microsoft.com/lucian/2015/10/23/how-to-call-uwp-apis-from-a-desktop-vbc-app/#comment-7985"><span style="color: #0563c1;font-family: Calibri">https://blogs.msdn.microsoft.com/lucian/2015/10/23/how-to-call-uwp-apis-from-a-desktop-vbc-app/#comment-7985</span></a><span style="color: #000000;font-family: Calibri"> </span>

<span style="color: #000000;font-family: Calibri">I was able to get this to work from desktop code.</span>

<span><span>        </span></span><span>private</span><span> </span><span>async</span><span> </span><span>Task</span><span>&lt;</span><span>string</span><span>&gt; ExtractText(</span><span>string</span><span> filename)</span>

<span><span>        </span>{</span>

<span><span>            </span></span><span>OcrEngine</span><span> ocrEngine = </span><span>OcrEngine</span><span>.TryCreateFromLanguage(</span><span>new</span><span> Windows.Globalization.</span><span>Language</span><span>(</span><span>"EN-US"</span><span>));</span>

<span><span>            </span></span><span>SoftwareBitmap</span><span> softwareBitmap = GetSoftwareBitmap(filename);</span>

<span><span>            </span></span><span>var</span><span> ocrResult = </span><span>await</span><span> ocrEngine.RecognizeAsync(softwareBitmap);</span>

<span><span>            </span></span><span>string</span><span> extractedText = </span><span>""</span><span>;</span>

<span><span>            </span></span><span>if</span><span> (ocrResult != </span><span>null</span><span>)</span>

<span><span>            </span>{</span>

<span><span>                </span></span><span>foreach</span><span> (</span><span>var</span><span> line </span><span>in</span><span> ocrResult.Lines)</span>

<span><span>                </span>{</span>

<span><span>                    </span></span><span>// Iterate over words in line.</span>

<span><span>                    </span></span><span>foreach</span><span> (</span><span>var</span><span> word </span><span>in</span><span> line.Words)</span>

<span><span>                    </span>{</span>

<span><span>        </span><span>                </span>extractedText += word.Text + </span><span>" "</span><span>;</span>

<span><span>                    </span>}</span>

<span> </span>

<span><span>                    </span>extractedText += </span><span>Environment</span><span>.NewLine;</span>

<span><span>                </span>}</span>

<span><span>            </span>}</span>

<span> </span>

<span><span>            </span></span><span>return</span><span> extractedText;</span>

<span><span>        </span>}</span>

<span> </span>

<span><span>        </span></span><span>private</span><span> </span><span>static</span><span> </span><span>unsafe</span><span> </span><span>SoftwareBitmap</span><span> GetSoftwareBitmap(</span><span>string</span><span> filename)</span>

<span><span>        </span>{</span>

<span><span>            </span></span><span>WriteableBitmap</span><span> writeableBitmap = </span><span>null</span><span>;</span>

<span><span>            </span></span><span>using</span><span> (</span><span>FileStream</span><span> file = </span><span>File</span><span>.Open(filename, </span><span>FileMode</span><span>.Open))</span>

<span><span>            </span>{</span>

<span><span>                </span></span><span>BitmapSource</span><span> srcImage = </span><span>BitmapDecoder</span><span>.Create(file,</span>

<span><span>                    </span></span><span>BitmapCreateOptions</span><span>.None, </span><span>BitmapCacheOption</span><span>.OnLoad).Frames[0];</span>

<span><span>                </span></span><span lang="DE">if</span><span lang="DE"> (srcImage.Format != </span><span lang="DE">PixelFormats</span><span lang="DE">.Bgra32)</span>

<span lang="DE"><span>                    </span></span><span>srcImage = </span><span>new</span><span> </span><span>FormatConvertedBitmap</span><span>(srcImage, </span><span>PixelFormats</span><span>.Bgra32, </span><span>null</span><span>, 0);</span>

<span><span>               </span><span> </span>writeableBitmap = </span><span>new</span><span> </span><span>WriteableBitmap</span><span>(srcImage);</span>

<span><span>            </span>}</span>

<span> </span>

<span><span>            </span>writeableBitmap.Lock();</span>

<span><span>            </span></span><span>var</span><span> pixels = </span><span>new</span><span> </span><span>byte</span><span>[writeableBitmap.PixelWidth * writeableBitmap.PixelHeight * 4];</span>

<span><span>            </span></span><span>byte</span><span>* pBuf = (</span><span>byte</span><span>*)writeableBitmap.BackBuffer;</span>

<span><span>            </span></span><span>for</span><span> (</span><span>int</span><span> i = 0; i &lt; pixels.Length; i++)</span>

<span><span>                </span></span><span lang="DE">pixels[i] = *pBuf++;</span>

<span lang="DE"><span>            </span></span><span lang="DE">var</span><span lang="DE"> ibuffer = pixels.AsBuffer();</span>

<span lang="DE"><span>            </span>writeableBitmap.Unlock();</span>

<span lang="DE"> </span>

<span lang="DE"><span>            </span></span><span lang="DE">SoftwareBitmap</span><span lang="DE"> softwareBitmap = </span><span lang="DE">new</span><span lang="DE"> </span><span lang="DE">SoftwareBitmap</span><span lang="DE">(</span><span lang="DE">BitmapPixelFormat</span><span lang="DE">.Bgra8, writeableBitmap.PixelWidth, writeableBitmap.PixelHeight);</span>

<span lang="DE"><span>            </span></span><span>softwareBitmap.CopyFromBuffer(ibuffer);</span>

<span><span>            </span></span><span>return</span><span> softwareBitmap;</span>

<span><span>        </span>}</span>

<span style="color: #000000;font-family: Calibri">Here is a sample app that I have prepared, you are free to use this in commercial projects.</span><span style="color: #000000;font-family: Calibri"> </span>

<a href="https://theuxblog20160710035436.azurewebsites.net/ocrdesktop.zip"><span style="color: #0563c1;font-family: Calibri">https://theuxblog20160710035436.azurewebsites.net/ocrdesktop.zip</span></a><span style="color: #000000;font-family: Calibri"> </span>

<span lang="EN-US" style="margin: 0px;color: #333333;font-family: 'Calibri',sans-serif;font-size: 13.5pt">Paul Tallett, UX Global Practice, Microsoft UK</span>

<strong><span lang="EN-US" style="margin: 0px;color: #333333;font-family: 'Calibri',sans-serif">Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the </span></strong><span lang="EN-US" style="margin: 0px;color: #333333;font-family: 'Calibri',sans-serif"><a href="https://www.microsoft.com/en-us/legal/intellectualproperty/copyright"><span style="color: #0563c1">Terms of Use</span></a>.</span>

&nbsp;

<span lang="EN-US"><span style="color: #000000;font-family: Calibri"> </span></span>]]></content:encoded>
    </item>
    <item>
      <title>Custom TreeView for WinRT Windows 10 XAML Store Apps</title>
      <link>https://docs.microsoft.com/archive/blogs/theuxblog/custom-treeview-for-winrt-windows-10-xaml-store-apps</link>
      <pubDate>Sun, 10 Jul 2016 08:31:33 GMT</pubDate>
      <dc:creator><![CDATA[ptallett]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/theuxblog/?p=155</guid>
      <description><![CDATA[&nbsp; There are a few implementations of tree views for WinRT available, but none of them did...]]></description>
      <content:encoded><![CDATA[<p><font size="3"></font>&nbsp;</p> <p><font size="3">There are a few implementations of tree views for WinRT available, but none of them did exactly what I wanted. I wanted something very simple (300 lines of code) that I could tailor the look and feel easily without getting bogged down in generic hierarchical data templates etc. I’ve written 2 or 3 tree views but the most recent one came out pretty well so I thought I would share.</font></p> <p><font size="3">The basic idea is to use a ListView and only display the expanded items, and indent them depending on their level in the hierarchy. By using a ListView, we get all the rich templating and mouse over behaviours plus the entrance transitions etc.</font></p> <p><font size="3">A couple of caveats with this implementation. Rather than go for a generic solution, the tree view has knowledge of the items it is displaying (Item and ItemFolder in the sample). So if you use it, you will have to modify it to understand your data types.</font></p> <p><font size="3">Secondly, it stores the expanded state of the nodes in the data model, which means you can’t have two tree views operating on the same data otherwise they will expand and collapse together as they share the same data.</font></p> <p><font size="3">I took the hit on these two things for simplicity’s sake, but the approach will not appeal to the purists.</font></p> <p><font size="3">The tree view assumes it has a collection of Item’s and ItemFolder’s as its ItemSource, and that an ItemFolder has a Children property containing another similar list.</font></p> <p><font size="3">I chose to use files and folders for the sample, but clearly you could display any tree structure.</font></p> <p><font size="3"></font>&nbsp;</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/07/image306.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/07/image_thumb275.png" width="1150" height="692"></a></p> <p>&nbsp;</p> <p><font size="3">I’ll not explain the control in any great detail as it would take up too much space, but it is worth pointing out one rather cool method in ItemFolder – the AllChildren property. I found when working with trees of data I was constantly writing recursive functions as these are the easiest way to process trees, but it started getting quite tiresome, so I came up with this neat little property:</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">public IEnumerable AllChildren<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp; get<br>&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (Item child in this.Children)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; yield return child;</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ItemFolder folder = child as ItemFolder;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (folder != null &amp;&amp; folder.Children.Count &gt; 0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (Item grandChild in folder.AllChildren)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; yield return grandChild;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp; }<br>}</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">This hides the recursion in the AllChildren property and allows you to process the tree as a flat list with a foreach statement.</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">foreach(var child in parent.AllChildren)</font></p> <p><font size="3">{</font></p> <p><font size="3">}</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">Its the first time I’ve use yield and it really helps when working with trees.</font></p> <p><font size="3">Note that the tree view watches all its children, so if you add something into one of the Children collections, it will automatically update.</font></p> <p>&nbsp;</p> <p><font size="3">Hope you like it, here is the sample code. You are free to use it in your code, even for commercial use.</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3"><a title="https://theuxblog20160710035436.azurewebsites.net/TreeViewSample.zip" href="https://theuxblog20160710035436.azurewebsites.net/TreeViewSample.zip">https://theuxblog20160710035436.azurewebsites.net/TreeViewSample.zip</a></font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">Enjoy!</font></p> <p><font size="3">Paul Tallett, UX Global Practice, Microsoft UK</font></p> <p><font size="3"></font></p> <p><strong>Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the </strong><a href="https://www.microsoft.com/en-us/legal/intellectualproperty/copyright">Terms of Use</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Enumerating installed fonts using SharpDX DirectWrite and XAML in a Windows 10 Store App (UWP)</title>
      <link>https://docs.microsoft.com/archive/blogs/theuxblog/enumerating-installed-fonts-using-sharpdx-directwrite-and-xaml-in-a-windows-10-store-app-uwp</link>
      <pubDate>Sun, 10 Jul 2016 03:38:32 GMT</pubDate>
      <dc:creator><![CDATA[ptallett]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/theuxblog/?p=125</guid>
      <description><![CDATA[&nbsp; When dealing with fonts, many apps show a Combo Box listing all the fonts installed on the...]]></description>
      <content:encoded><![CDATA[<p>&nbsp;</p> <p><font size="3">When dealing with fonts, many apps show a Combo Box listing all the fonts installed on the system and allow the user to choose from them. However, this functionality is not directly supported in XAML, so to implement this in a Windows Store Universal Windows Platform (UWP) app we need to dip into some SharpDX.</font></p> <p><font size="3">Here’s what the sample looks like:</font></p> <p><font size="3"></font>&nbsp;</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/07/image305.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/07/image_thumb274.png" width="987" height="729"></a></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">The combo box lists all the installed fonts and allows the user to pick from one, setting the font on the text box.</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">This is relatively easy once you’ve added a reference to SharpDX as it provides a GetSystemFontCollection method that pretty much does this. We just wrap it in some code to make it easy to call.</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">// Code taken straight from SharpDX\Samples\DirectWrite\FontEnumeration\Program.cs<br>public static List&lt;InstalledFont&gt; GetFonts()<br>{<br>&nbsp;&nbsp;&nbsp; if(fonts != null)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return fonts;<br>&nbsp;&nbsp;&nbsp; var fontList = new List&lt;InstalledFont&gt;();</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp; using (var factory = new Factory())<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; using (var fontCollection = factory.GetSystemFontCollection(false))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var familyCount = fontCollection.FontFamilyCount;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; familyCount; i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; using (var fontFamily = fontCollection.GetFontFamily(i))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var familyNames = fontFamily.FamilyNames;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int index;</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!familyNames.FindLocaleName(CultureInfo.CurrentCulture.Name, out index))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; familyNames.FindLocaleName("en-us", out index);</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string name = familyNames.GetString(index);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string display = name;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; using (var font = fontFamily.GetFont(index))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (font.IsSymbolFont)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; display = "Segoe UI";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fontList.Add(new InstalledFont { Name = name, DisplayFont = display });<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch { }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Corrupted font files throw an exception - ignore them<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp; fontList.Sort();<br>&nbsp;&nbsp;&nbsp; fonts = fontList;<br>&nbsp;&nbsp;&nbsp; return fontList;<br>}</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">I noticed when calling this that some systems have corrupt font files and the above call throws an exception when querying for IsSymbolFont. It is much better to have the exception in this method than later when we try to use the font, as here we can just ignore it.</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">I have provided a sample project with all the code hooked up. You are free to use it in your code, even for commercial use.</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3"><a title="https://theuxblog20160710035436.azurewebsites.net/FontSample.zip" href="https://theuxblog20160710035436.azurewebsites.net/FontSample.zip">https://theuxblog20160710035436.azurewebsites.net/FontSample.zip</a></font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">Enjoy!</font></p> <p><font size="3">Paul Tallett, UX Global Practice, Microsoft UK</font></p> <p><strong>Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the </strong><a href="https://www.microsoft.com/en-us/legal/intellectualproperty/copyright">Terms of Use</a>.</p> <p><font size="3"></font></p>]]></content:encoded>
    </item>
    <item>
      <title>Custom app theming using data binding on Windows 10 XAML Store Apps</title>
      <link>https://docs.microsoft.com/archive/blogs/theuxblog/custom-app-theming-using-data-binding-on-windows-10-xaml-store-apps</link>
      <pubDate>Sun, 10 Jul 2016 02:35:39 GMT</pubDate>
      <dc:creator><![CDATA[ptallett]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/theuxblog/?p=96</guid>
      <description><![CDATA[&nbsp; XAML provides a rich framework for providing beautiful, responsive designs with many built in...]]></description>
      <content:encoded><![CDATA[<p><font size="3"></font>&nbsp;</p> <p><font size="3">XAML provides a rich framework for providing beautiful, responsive designs with many built in controls to simplify the building of apps. However, it is often a requirement to allow the user to choose from a set of themes in order to change the appearance of the entire app. For example, a dark and a light theme, maybe a blue or a red theme, or maybe you want to implement a daytime and night-time mode. The ThemeResource scheme is available in UWP apps, but does not allow the theme to be changed dynamically at runtime.</font></p> <p><font size="3">In this article I outline a simple extensible method based on data binding that allows you to define an unlimited set of themes for your app, and to allow the user to pick from them dynamically.</font></p> <p><font size="3">Here are some screenshots of the sample in both dark and light themes.</font></p> <p><font size="3"></font>&nbsp;</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/07/image303.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/07/image_thumb272.png" width="643" height="454"></a></p> <p>&nbsp;</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/07/image304.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/07/image_thumb273.png" width="654" height="462"></a></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">By clicking the “Switch” button, the app changes appearance completely. Notice that the app title bar also changes colour.</font></p> <p><font size="3">We start by defining a class in Theme.cs that contains properties for all of the different colours used in our UI. This is completely extensible, you can add as many colour properties as you like for each theme, but the more you add, the more work it is to define a new custom theme. In the sample we really only use a small number of properties, but you can define mouse over properties and disabled properties to control all aspects of your UI. This is also not limited to brushes and colours, you could add other data types to this.</font></p> <p><font size="3">Then, App.xaml, we define the themes. We only defined two, a light and a dark theme, but you can have as many as you like:</font></p> <p>&nbsp;</p> <blockquote> <p><font size="3">&lt;local:ThemeManager x:Key="ThemeManager"/&gt;<br>&lt;local:Theme x:Key="DarkTheme"&nbsp; ForegroundColor="#123456" BackgroundColor="Black"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="3">TextColor="White" PanelBackgroundColor="#FF2b2b2b"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PopupPanelBackgroundColor="#12345678" SettingsBackgroundColor="#12345678"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ViewerBackgroundColor="#FF222222"/&gt;<br>&lt;local:Theme x:Key="LightTheme" ForegroundColor="#123456" BackgroundColor="White"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TextColor="Black" PanelBackgroundColor="#FFEEEEEE"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PopupPanelBackgroundColor="#12345678" SettingsBackgroundColor="#12345678"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ViewerBackgroundColor="White"/&gt;</font></p></blockquote> <p><font size="3"></font>&nbsp;</p> <p><font size="3">Notice also the definition for ThemeManager. This is the class that will maintain the current theme for us and allow us to switch themes. ThemeManager is a singleton, and we add some code to our ViewModel to allow us to access the ThemeManager from code behind.</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">private ThemeManager themeManager = null;<br>public ThemeManager ThemeManager<br>{<br>&nbsp;&nbsp;&nbsp; get<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (this.themeManager == null)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; App app = (App.Current) as App;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.themeManager = app.Resources["ThemeManager"] as ThemeManager;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.themeManager;<br>&nbsp;&nbsp;&nbsp; }<br>}</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">This is important to make sure we are accessing the same ThemeManager instance in code as we do declaratively in the XAML markup.</font></p> <p><font size="3">Then, somewhere convenient, we load the themes:</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">private void MainPage_Loaded(object sender, RoutedEventArgs e)<br>{<br>&nbsp;&nbsp;&nbsp; this.DataContext = ViewModel.Current;<br>&nbsp;&nbsp;&nbsp; ViewModel.Current.ThemeManager.Load();<br>}</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">Now all we need to do is in our XAML definitions of our UI, we must not use fixed colours but must always reference the theme colours:</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">&lt;TextBlock Foreground="{Binding CurrentTheme.TextBrush, Source={StaticResource ThemeManager}}" FontSize="30" Text="This is some sample text" Grid.Row="1" HorizontalAlignment="Center"/&gt;<br>&lt;Button Content="Switch" FontSize="15" Grid.Row="2" Margin="0,10" HorizontalAlignment="Center" Click="Button_Click"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Foreground="{Binding CurrentTheme.TextBrush, Source={StaticResource ThemeManager}}" <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BorderBrush="{Binding CurrentTheme.TextBrush, Source={StaticResource ThemeManager}}" BorderThickness="1"/&gt;</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">Now when we change the CurrentTheme property in code, possibly from our settings page, all of our UI changes colour as the databinding NotifyPropertyChanged will fire.</font></p> <p><font size="3">Because it is dynamic, the user gets immediate feedback of how the UI will look with the new theme. It is also easy to save the current theme index in a local settings file and restore it when the app starts up, so that the user’s preferences are kept (I have commented out this code). If you add themes, add them to the end of the list for backwards compatibility, so that older versions of your settings file will reference the correct chosen colour scheme.</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">I have included a sample project with all the code. You are free to use it in your code, even for commercial use.</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3"><a title="https://theuxblog20160710035436.azurewebsites.net/themingsample.zip" href="https://theuxblog20160710035436.azurewebsites.net/themingsample.zip">https://theuxblog20160710035436.azurewebsites.net/themingsample.zip</a></font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">Enjoy!</font></p> <p><font size="3">Paul Tallett, UX Global Practice, Microsoft UK</font></p> <p><strong>Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the </strong><a href="https://www.microsoft.com/en-us/legal/intellectualproperty/copyright">Terms of Use</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Multiple Windows/Views in a Windows 10 XAML Store App</title>
      <link>https://docs.microsoft.com/archive/blogs/theuxblog/multiple-windowsviews-in-a-windows-10-xaml-store-app</link>
      <pubDate>Sun, 10 Jul 2016 00:50:15 GMT</pubDate>
      <dc:creator><![CDATA[ptallett]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/theuxblog/?p=56</guid>
      <description><![CDATA[&nbsp; Back in Windows 8, Modern Apps were full screen and could only have one window open. In...]]></description>
      <content:encoded><![CDATA[<p>&nbsp;</p> <p><font size="3">Back in Windows 8, Modern Apps were full screen and could only have one window open. In Windows 10, a Universal Application (UWP) can have multiple windows (views) open at once so that a user can, for example, work on multiple documents at once, and switch between windows just like classic Win32 applications such as Word or PowerPoint.</font></p> <p><font size="3">In this post, I’ll show you just how easy it is to do that, and how all UWP apps should implement multiple windows if it is appropriate for their functionality.</font></p> <p><font size="3">All you need to be multi-window is to call the View management APIs in your App.xaml.cs. In your OnLaunched method just add the following code:</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">protected override async void OnLaunched(LaunchActivatedEventArgs e)<br>{<br>&nbsp;&nbsp;&nbsp; Frame rootFrame = Window.Current.Content as Frame;<br>&nbsp;&nbsp;&nbsp; if (rootFrame == null)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // First activation<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rootFrame = new Frame();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rootFrame.NavigationFailed += OnNavigationFailed;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Window.Current.Content = rootFrame;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (rootFrame.Content == null)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rootFrame.Navigate(typeof(MainPage), e.Arguments);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Window.Current.Activate();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dispatchers.Add(CoreWindow.GetForCurrentThread().Dispatcher);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Subsequent activations - create new view/UI thread<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var view = CoreApplication.CreateNewView();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int windowId = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; await view.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; windowId = ApplicationView.GetApplicationViewIdForWindow(CoreWindow.GetForCurrentThread());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var frame = new Frame();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; frame.Navigate(typeof(MainPage), null);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Window.Current.Content = frame;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Window.Current.Activate();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ApplicationView.GetForCurrentView().Consolidated += View_Consolidated;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Run this on the last dispatcher so the windows get positioned correctly<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool viewShown;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; await dispatchers[dispatchers.Count - 1].RunAsync(CoreDispatcherPriority.Normal, async () =&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(windowId); });<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dispatchers.Add(view.Dispatcher);<br>&nbsp;&nbsp;&nbsp; }<br>}</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">Each view gets its own UI thread. Note how I keep a list of all the dispatchers as this can be useful if you need to do operations in the other windows. It is really important to avoid cross thread access of UI resources as this will crash your application with a cross-thread exception. The solution I use is to have completely separate ViewModel’s for each thread, that are easily accessed in code with ViewModel.Current to reference the ViewModel for the current thread.</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">public class ViewModel<br>{<br>&nbsp;&nbsp;&nbsp; private static Dictionary&lt;CoreDispatcher, ViewModel&gt; viewModels = new Dictionary&lt;CoreDispatcher, ViewModel&gt;();<br>&nbsp;&nbsp;&nbsp; private static int count = 0;<br>&nbsp;&nbsp;&nbsp; public static ViewModel Current<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lock (viewModels)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (dispatcher == null)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new ArgumentException("ViewModel.Current must be called from a UI thread");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ViewModel viewModel = null;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (viewModels.TryGetValue(dispatcher, out viewModel))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return viewModel;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; viewModel = new ViewModel();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; viewModels[dispatcher] = viewModel;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; viewModel.InstanceId = ++count;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // This is just for the demo project<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return viewModel;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp; public int InstanceId { get; set; }<br>}</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">Calling ViewModel.Current always returns the correct ViewModel corresponding to the View’s UI thread, so it is very difficult to run into cross-thread problems.</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">Here is a test project with all the code. Run it, then right click the taskbar icon and run more instances. You will see that each view gets its own ViewModel and displays different content.</font></p> <p><font size="3"></font>&nbsp;</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/07/image302.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/07/image_thumb271.png" width="933" height="883"></a></p> <p>&nbsp;</p> <p><font size="3">The test project can be downloaded here: You are free to use it in your code, even for commercial use.</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3"><a title="https://theuxblog20160710035436.azurewebsites.net/MultiWindowSample.zip" href="https://theuxblog20160710035436.azurewebsites.net/MultiWindowSample.zip">https://theuxblog20160710035436.azurewebsites.net/MultiWindowSample.zip</a></font></p> <p>&nbsp;</p> <p><font size="3">Enjoy!</font></p> <p><font size="3">Paul Tallett, UX Global Practice, Microsoft UK</font></p> <p><strong>Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the </strong><a href="https://www.microsoft.com/en-us/legal/intellectualproperty/copyright">Terms of Use</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Outline text from a Windows 10 Store XAML App using SharpDX</title>
      <link>https://docs.microsoft.com/archive/blogs/theuxblog/outline-text-from-a-windows-10-store-xaml-app-using-sharpdx</link>
      <pubDate>Sat, 09 Jul 2016 11:08:53 GMT</pubDate>
      <dc:creator><![CDATA[ptallett]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/theuxblog/?p=36</guid>
      <description><![CDATA[&nbsp; I recently needed to draw text outlines on one of my projects from a Windows 10 Store app....]]></description>
      <content:encoded><![CDATA[<p><font size="3"></font>&nbsp;</p> <p><font size="3">I recently needed to draw text outlines on one of my projects from a Windows 10 Store app. This is not directly supported by XAML so I had to use some SharpDX DirectX code to retrieve the font outlines and then draw as a Path object. The result can be seen here.</font></p> <p><font size="3"></font>&nbsp;</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/07/image298.png"><font size="3"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/07/image_thumb267.png" width="824" height="527"></font></a></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">I packaged up the solution into an easy to use User Control so the XAML used for the above was easy:</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">&lt;local:OutlineTextBlock Text="Hello World!" FontSize="100" FontFamily="Ravie" StrokeThickness="2" VerticalAlignment="Center" HorizontalAlignment="Center"&gt;<br>&nbsp;&nbsp;&nbsp; &lt;local:OutlineTextBlock.Stroke&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;LinearGradientBrush StartPoint="0.5,1" EndPoint="0.5,0"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;GradientStop Color="Red" Offset="0.3"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;GradientStop Color="Green" Offset="1"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/LinearGradientBrush&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/local:OutlineTextBlock.Stroke&gt;<br>&lt;/local:OutlineTextBlock&gt;</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">You can just use the above code to draw text outlines in your project, but if you want to understand how this works, read on.</font></p> <p><font size="3">Fetching the text outlines was quite tricky and involved implementing a DirectX custom text renderer which renders the text into a custom Geometry Sink which in turn converts the font outlines into a PathGeometry which can be used to create a XAML Path object. I found this post which was very nearly what I needed but it still took a lot of work to turn it into the finished result. </font><a title="https://stackoverflow.com/questions/7563798/how-to-implement-the-outline-effect-on-text-with-windowsapicodepack" href="https://stackoverflow.com/questions/7563798/how-to-implement-the-outline-effect-on-text-with-windowsapicodepack" target="_blank"><font size="3">https://stackoverflow.com/questions/7563798/how-to-implement-the-outline-effect-on-text-with-windowsapicodepack</font></a><font size="3">&nbsp;</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">Here is the code:</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp; public Sink SimplifiedGeometrySink { get; set; }<br>&nbsp;&nbsp;&nbsp; public OutlineTextRenderer(RenderTarget surface, SharpDX.Direct2D1.Brush brush)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _factory = surface.Factory;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _surface = surface;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _brush = brush;<br>&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp; public Result DrawGlyphRun(object clientDrawingContext, float baselineOriginX, float baselineOriginY, MeasuringMode measuringMode, SharpDX.DirectWrite.GlyphRun glyphRun, SharpDX.DirectWrite.GlyphRunDescription glyphRunDescription, ComObject clientDrawingEffect)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; using (SharpDX.Direct2D1.PathGeometry path = new SharpDX.Direct2D1.PathGeometry(_factory))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; using (GeometrySink sink = path.Open())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; glyphRun.FontFace.GetGlyphRunOutline(glyphRun.FontSize, glyphRun.Indices, glyphRun.Advances, glyphRun.Offsets, glyphRun.IsSideways, (glyphRun.BidiLevel % 2) &gt; 0, sink);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sink.Close();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.SimplifiedGeometrySink = new Sink();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; path.Simplify(GeometrySimplificationOption.CubicsAndLines, (SharpDX.Direct2D1.SimplifiedGeometrySink)this.SimplifiedGeometrySink);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new Result();<br>&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp; public Result DrawInlineObject(object clientDrawingContext, float originX, float originY, SharpDX.DirectWrite.InlineObject inlineObject, bool isSideways, bool isRightToLeft, ComObject clientDrawingEffect)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new Result();<br>&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp; public Result DrawStrikethrough(object clientDrawingContext, float baselineOriginX, float baselineOriginY, ref SharpDX.DirectWrite.Strikethrough strikethrough, ComObject clientDrawingEffect)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new Result();<br>&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp; public Result DrawUnderline(object clientDrawingContext, float baselineOriginX, float baselineOriginY, ref SharpDX.DirectWrite.Underline underline, ComObject clientDrawingEffect)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SharpDX.Direct2D1.DeviceContext d2dContext = clientDrawingContext as SharpDX.Direct2D1.DeviceContext;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RawRectangleF rect = new RawRectangleF(0, underline.Offset, underline.Width, underline.Offset + underline.Thickness);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SharpDX.Direct2D1.RectangleGeometry geom = new SharpDX.Direct2D1.RectangleGeometry(d2dContext.Factory, rect);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; geom.Simplify(GeometrySimplificationOption.Lines, this.SimplifiedGeometrySink);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new Result();<br>&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp; public float GetPixelsPerDip(object clientDrawingContext)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp; public bool IsPixelSnappingDisabled(object clientDrawingContext)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br>&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp; RawMatrix3x2 PixelSnapping.GetCurrentTransform(object clientDrawingContext)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new RawMatrix3x2();<br>&nbsp;&nbsp;&nbsp; }<br>}</font></p> <p><font size="3">public class Sink : SharpDX.Direct2D1.SimplifiedGeometrySink<br>{<br>&nbsp;&nbsp;&nbsp; Windows.UI.Xaml.Media.PathFigureCollection figures = new Windows.UI.Xaml.Media.PathFigureCollection();<br>&nbsp;&nbsp;&nbsp; Windows.UI.Xaml.Media.PathFigure currentFigure = null;<br>&nbsp;&nbsp;&nbsp; public Windows.UI.Xaml.Media.PathFigureCollection PathFigureCollection { get { return figures; } }<br>&nbsp;&nbsp;&nbsp; public IDisposable Shadow<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp; public void BeginFigure(RawVector2 startPoint, FigureBegin figureBegin)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; currentFigure = new Windows.UI.Xaml.Media.PathFigure { StartPoint = new Windows.Foundation.Point(startPoint.X, startPoint.Y) };<br>&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp; public void AddBeziers(SharpDX.Direct2D1.BezierSegment[] beziers)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (SharpDX.Direct2D1.BezierSegment bez in beziers)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; currentFigure.Segments.Add(new Windows.UI.Xaml.Media.BezierSegment<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Point1 = new Windows.Foundation.Point(bez.Point1.X, bez.Point1.Y),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Point2 = new Windows.Foundation.Point(bez.Point2.X, bez.Point2.Y),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Point3 = new Windows.Foundation.Point(bez.Point3.X, bez.Point3.Y)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp; public void AddLines(RawVector2[] pointsRef)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (RawVector2 vect in pointsRef)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; currentFigure.Segments.Add(new Windows.UI.Xaml.Media.LineSegment { Point = new Windows.Foundation.Point(vect.X, vect.Y) });<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp; public void EndFigure(FigureEnd figureEnd)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; currentFigure.IsClosed = figureEnd == FigureEnd.Closed;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; figures.Add(currentFigure);<br>&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp; public void Close()<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp; public void Dispose()<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; figures = new Windows.UI.Xaml.Media.PathFigureCollection();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; currentFigure = null;<br>&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp; public void SetFillMode(SharpDX.Direct2D1.FillMode fillMode)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">&nbsp;&nbsp;&nbsp; public void SetSegmentFlags(SharpDX.Direct2D1.PathSegment vertexFlags)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; }</font></p> <p><font size="3">I have included a demo project with all the code. You are free to use it in your code, even for commercial use.</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3"><a title="https://theuxblog20160710035436.azurewebsites.net/OutlineTextDemo.zip" href="https://theuxblog20160710035436.azurewebsites.net/OutlineTextDemo.zip">https://theuxblog20160710035436.azurewebsites.net/OutlineTextDemo.zip</a></font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">Enjoy!</font></p> <p><font size="3">Paul Tallett, UX Global Practice, Microsoft UK</font></p> <p><strong>Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the </strong><a href="https://www.microsoft.com/en-us/legal/intellectualproperty/copyright">Terms of Use</a>.  <p><font size="3"></font></p>]]></content:encoded>
    </item>
  </channel>
</rss>