Corrado's Blog 2.0

Online thoughts of a technology funatic

UWP Localization inside a library

Many of my blog posts comes from personal real world needs, since many of them requires more than just an internet search, when i struggle with some of them I try to share my experience with the online community.
The goal of this post is very simple at first sight: Localize a control that resides inside a control library and make the language used by the control different from the OS one (e.g. Control text in German while running on an English version of Windows)
The master of UWP localization documentation is this MSDN link, so I won’t add anything else since it will just result in a duplicate,
Following the MSDN documentation I’ve created two projects: A UWP client (LocalizationInLib) and a control library project (ControlLibrary) inside the latter I’ve created a Strings folder containing the default localization file Resources.resw and inside of it an additional “it” folder containing the italian translation of master Resources.resw content.

Here’s the project structure

image

and here’s what’s inside both Resources.resw files

Default
image

Italian
image

Nothing new until now if you read the previously mentioned MSDN link.

Let’s now define our simple MyTimer control in XAML and a SetLanguage method that accept the control culture to use.

This way we can invoke SetLanguage from the client application depending of what culture the user selected in main app.
We have now reached the core point of this post and what made me hit the head several times: what code should I use to load the proper resources at runtime? after many tests and investigations here’s what I ended up with:

Important detail is to use the proper namespace inside GetForViewIndependentUse otherwise the method will fail.
Just few lines of code, but took me some time to figure out how to properly combine them, so I hope this will help you in future.

Detect Application closing in UWP

Nearly every application when user closes it using the “X” button on upper right corner prompts something like this

image

Asking user if he wants to save actual work or cancel closing operation. 
Doing this in a UWP application is far from trivial, sounds strange uh? Smile

Despite some options are available (like CoreWindow esposes a Closed event but it never fires) the only available solution sounded to be this one which is unfortunately complex and unreliable. 
From Creators update (version 1703) a new class SystemNavigationManagerPreview  has been added and this class exposes a CloseRequested event (yeah!)
Ok, let’s see how it works, let’s fire up a brand new UWP app inside Visual Studio and let’s add this code inside MainPage.Xaml codebehind.

Let’s put a breakpoint inside OnCloseRequested method, run the app and try closing the window clicking the upper right “X” button.
The breakpoint doesn’t it right? so What’s wrong with that? nothing indeed, we just miss an important detail:  In order to work, you need to add a restricted capability inside package.appmanifest, the one we need is AppClose Confirmation that MSDN describes as: confirmAppClose restricted capability allows apps to close themselves, their own windows, and delay the closing of their app.

Ok, let’s manually edit the manifest file adding following lines:

Inside Package tag: xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"

then add rescap to IgnorableNamespacesAttribute: IgnorableNamespaces="uap mp rescap"
Then inside Capabilities tag:
<Capabilities>
    <Capability Name="internetClient" />
    <rescap:Capability Name="confirmAppClose"/>
  </Capabilities>

Very important: confirmAppClose capability must be listed before any optional DeviceCapability otherwise it won’t work.
Let’s  now try again and… yes! it works! Smile
You can now do whatever you want inside the OnCloseRequest handler, like showing a dialog and if user denies closing setting SystemNavigationCloseRequestedPreviewEventArgs.Handled=true to prevent app from closing.

Please take care of the note inside capabilities declaration page on MSDN:

Some of these restricted capabilities are almost never approved for apps submitted to the Store, except in very specific and limited circumstances. These capabilities are called out in the table below. We recommend not declaring these capabilities in your app if you plan to distribute it through the Store.

I see no reason why Microsoft should prevent this but take note and don’t forget to mention its use inside portal Submission options page

Get unique Device Id and Application Id in UWP applications

Sometime you need to get a unique application identifier for your app together with a unique device id for internal processing.

Here’s the code you need:

A note regarding device identifier

As you might see from the involved API name SystemIdentification.GetSystemIdForPublisher() the returned value is unique for the same app publisher, if publisher changes the value changes as well.

Here are the Device Id characteristics

  • -Unique for each system
  • -On any particular system, all apps by the same publisher will get the same value for this ID (for all users). Conversely, apps by different publishers on the same system will obtain different IDs.
  • -Can be created offline
  • -Persists across restarts, reinstalls and upgrades of Windows, including clean installs (please see below for exceptions)
  • -Persists across most hardware modifications
  • -Available in OneCore

Playing with ParallaxView

Those of you who have some Windows Phone development experience will remember the Panorama control for sure.
Control had a nice effect where background content was moving slowly below foreground, this effects is named Parallax and you’ll be glad to know that, starting from Fall Creators Update you can have this effects easily back into your own UWP applications, thanks to ParallaxView parte of the new Fluid Design System.

Let’s see it in action:

Create a new UWP application targeting Fall Creators Update (unfortunately ParallaxView is not available on older platforms)

image_thumb1

let’s now add the ParallaxView to MainPage.Xaml

ParallaxView has a Child property that is used to represent the content that is scrolled slowly, in this case I defined it directly inside the ParallaxView.
The key property is Source that you can bind to an element that can be a ScrollViewer or an element that contains a ScrollViewer like a ListView or a RichTextBox. (Note: I tried to nest ListView definition directly inside ParallaxView but seems not to work)
Nothing special to mention about ListBox apart tha:

  1. -I used the ‘new’ PersonPicture control
  2. -The ListView must be placed after the ParallaxView definition, otherwise it wont work

Codebehind is quite straighforward:

The control supports both Verticaland and Horizontal scrolling and the most important property is probably Vertical/HorizontalShift that govers ‘how fast’ background scrolls, chose the one the best fits for you.
Using Vertical/HorizontalStartOffset it is possible to fine tune background scrolling behavior (play with them…)

Here’s final result, what do you think? Smile

parallax

Save Win2D CanvasControl content

Win2D is an easy-to-use Windows Runtime API for immediate mode 2D graphics rendering with GPU acceleration that is very helpful in some situations like real time or layered rendering.
This post is about how to save dynamically rendered content to a file for further external processing.

To give you an idea, let’s build a quick Win2D sample.

Create a blank new UWP project and add a NuGet reference to Win2D package

image

on MainPage.Xaml add following XAML

and this code on relative codebehind

if you now run the sample and change the value of the slider you will see the rectangle moving this way

cb

From the code is evident that each time the value of the slider changes we invalidate the CanvasControl so that OnDraw method gets called and content is redrawn with the new rectangle position.

To save CanvasControl content we basically need to draw actual content into an offscreen render target and use the SaveAsync method to get the stream content.
Here’s the code:

code just draws the same content into a CanvasRenderTarget representing the offscreen renderer and then gets that stream, the remaining code just saves it into a StorageFile.
Off course what’s drawn into offscreen renderer is up to you (as example you might add a watermark) and output format can be changed via CanvasFormatBitmap parameter.

HTH

Change x:Bind default binding mode

Recent release of Windows 10 introduced Complied Bindings, an type safe alternative to {Binding} syntax that add compile time checking and better performances, it can also be used in place of ElementName to bind to a UI element property.
In order to squeeze performances the default binding mode of compiled bindings is OneTime, this means that any further change of bound property after initial one won’t get propagated to bound UI property, and this, personally, is one of the most annoying things because i often use properties whose value changes and everytime i spend time figuring why they don’t before remembering of this different behavior.

To give you an example, let’s take this simple ViewModel

Page code behind

and page markup

if you try this code you will see that value doesn’t change when you click the button, this is because of default OneTime binding.

While you can change the behavior by adding Mode=OneWay to the Count binding, if you have many bindings and you’re targeting Fall Creators Update you can use the new attibute DefaultBindingMode

The plus of using this attribute is that it changes the default binding mode to all compiled bindings contained in the element where it is applied (and all childrens) saving a lot of time.

Nice! waited a long for this Smile

Beware of generated XAML in UWP

I admit, this is s strange blog post title but that’s what this post is going to talk about.

I’m working on a UWP app that has different min and target runtimes:

image

After doing some UI work with Visual Studio & Blend I’ve discovered that the app was crashing on machines without Anniversary edition installed. At the end of a debuggin session I’ve found the reason: The XAML template generated by the tools contains incompatible elements (resources mainly, but also new properties) that are not present on previous builds.

To give you an example, this is an extract from a ComboBox default template, generated by Blend when you use the Template->Edit copy feature:

10586

<Setter Property="Foreground"

Value="{ThemeResource SystemControlForegroundBaseHighBrush}" />

14393 (Anniversary)

<Setter Property="Foreground"

Value="{ThemeResource ComboBoxForeground}" />

The reason of this is because the tools generate the template from the Target version SDK and not the Min version SDK that might even not be present.

The team said that they’re going to give you some warnings in the future when situations like this happen, but in the meantime, at least when you’re doing design work, be sure to selected, the min target version SDK otherwise you might end up in troubles.