Quantcast
Channel: UWP – Metro Nuggets

Windows Universal Apps, Cimbalino and the App Back Button

$
0
0

One of the things you can add to a Desktop variant of a Universal Windows App is a back button that a developer can add to their app; this back button appears in the top left corner of the app. In order to use the back button, the developer needs to tell it to appear, as well as potentially wire up to the back button’s pressed event, but that’s not the Cimbalino way.

The Solution

In point of fact, the Cimbalino way for handling this is as simple as just use the NavigationService that comes with the Cimbalino toolkit. If this is something you use already, you get the back button’s visibility handled for you. Not only that, but with the standard Windows SDK, the phone’s back button pressed event and the Desktop back button’s pressed event are two different events, with two different arguments passed into them. So much for sharing code, right? Well this is where the Cimbalino way is better, because it takes care of all that for you and presents to you the same back key pressed event whether your app is running on the phone, or the desktop.

In the sample project, I’ve declared the NavigationService as a static object on App, but this will work if you’re injecting the NavigationService into your ViewModels in an MVVM environment.

BackKeyPressed

As mentioned, Cimbalino’s NavigationService allows you to have one event that you can use for both phone and desktop, so if we look at the code behind for Page2.xaml, we can see that in there, I’ve hooked up the BackKeyPressed event

        public Page2()
        {
            this.InitializeComponent();

            App.NavigationService.BackKeyPressed += NavigationServiceOnBackKeyPressed;
        }

        private void NavigationServiceOnBackKeyPressed(object sender, NavigationServiceBackKeyPressedEventArgs e)
        {
            e.Behavior = NavigationServiceBackKeyPressedBehavior.GoBack;
        }

This makes it very handy for sharing code and not having to worry about multiple event handlers for what is essentially the same thing.

Removal From Backstack

I hear you, what if you remove something from the backstack using the NavigationService’s RemoveEntry() method, well, if that removal causes the frame to no longer be able to go back, then the button is hidden, again, everything being taken care of for you.

Pfft, I’ll Do It Myself

So what about if you actually want to handle all this yourself? Well, this is easily configured too. When your app starts, just set the following:

Cimbalino.Toolkit.Services.NavigationService.HandleBackButtonVisibility = false;

By default, this is set to true, so it will automatically happen for you, you have to opt out of it.

Resources

Currently Cimbalino for UWP is not available via nuget, but it will be as soon as nuget figure out how this is all going to work. In the mean time, there is a branch on GitHub with Win10 support. Or if you want the precompiled dlls, you can find them in the sample app (just make sure you reference the Blend SDK in your project!).

SL



Introducing InteractiveToastExtensions for Universal Windows Apps

$
0
0

One of the new ways users can interact with your app is through notifications. Now, notifications are nothing new, for either Phone or Desktop, however, what’s been added to 10 is new. With Universal Windows Apps, you can now have interactive toast notifications. So what are these? They are like regular toast notifications only they can have elements that the user can interact with, maybe make a selection, or type in a response to something.

There’s an excellent blog post on MSDN that covers all the different types of interactions you can have within your app’s toasts, along with all the xml elements that are required in order to build your toast notification, but that does mean dealing with xml, and who likes that?!

The Solution

As always, I like to make things easy, and not having to deal with xml is high up on my list. So I’ve done the grunt work and created this little helper library that will more easily allow you to create your notifications.

So let’s look at a sample. I’m going to use one of the examples given in the aforementioned blog post so that there’s an easy point of reference for comparison.

This is the XML from the blog post:

<toast>
  <visual>
    <binding template="ToastGeneric">
      <text>Spicy Heaven</text>
      <text>When do you plan to come in tomorrow?</text>
      <image placement="appLogoOverride" src="A.png" />
    </binding>
  </visual>
  <actions>
    <input id="time" type="selection" defaultInput="2" >
  <selection id="1" content="Breakfast" />
  <selection id="2" content="Lunch" />
  <selection id="3" content="Dinner" />
    </input>
    <action activationType="background" content="Reserve" arguments="reserve" />
    <action activationType="background" content="Call Restaurant" arguments="call" />
  </actions>
</toast>

And this is the same notification created using the helper library:

var toast = new InteractiveToast();
var visual = new Visual();
visual.AddText(new Text("Spicy Heaven"));
visual.AddText(new Text("When do you plan to come in tomorrow?"));
visual.AddImage(new VisualImage("ms-appx:///Assets/Deadpool.png")
{
    ImagePlacement = ImagePlacement.AppLogoOverride
});

toast.SetVisual(visual);

var input = new ToastInput("time", ToastInputType.Selection)
{
    DefaultInput = "2"
};
input.AddSelection("1", "Breakfast");
input.AddSelection("2", "Lunch");
input.AddSelection("3", "Dinner");

toast.AddActionItem(input);

toast.AddActionItem(new ToastAction("Reserve", "reserve")
{
    ActivationType = ActivationType.Foreground
});
toast.AddActionItem(new ToastAction("Call Restaurant", "call")
{
    ActivationType = ActivationType.Foreground
});

var notification = toast.GetNotification();

ToastNotificationManager.CreateToastNotifier().Show(notification);

As you can see, certainly a lot friendlier. So what does that notification then look like?

On Desktop:
DesktopNotification

On Phone:
PhoneNotification

And there we have it.

Nuget: https://www.nuget.org/packages/InteractiveToastExtensions/
Source: https://github.com/ScottIsAFool/InteractiveToastExtensions

SL


My UWP Nuget Package is Missing a File?

$
0
0

When creating a nuget package that’s intended for a UWP, you’d be excused for creating your package in the same way you always have done, you include the new uap10.0 TFM (Target Framework Moniker) and drop your dll file(s) in there. This is 95% of it, but there’s a sneaky extra 5% that you still need to do, otherwise, whilst your package will still be valid, and will still get pulled into a UWP project, that project won’t be able to build.

The Solution

If you look in solution explorer within Visual Studio at your project, and expand the Properties section, you’ll see something like this:
image

Note that rd.xml file. That’s the file you’re missing. This file is required if you’re doing anything special with .NET Native builds, but more info on that can actually be read in the xml itself.

Now, in your nuget package, you need to have the following structure:
image

That xml file needs to live in uap10.0\< PROJECTNAME >\Properties\< PROJECTNAME >.rd.xml

Pop that in and then your package is good to go.

SL


Personalisation, Cimbalino and Universal Windows Apps

$
0
0

With Windows 10, two key areas of personalisation for a user are the lock screen and the wallpaper images, and this is both on phone and desktop. And on both you’ve always been able to set the lock screen image (for now we’ll just forget that WPA8.1 apps couldn’t!), but setting the wallpaper was something you couldn’t do in either desktop or phone. Now that’s changing with Windows 10. Whilst the APIs for settings these aren’t the most complicated ones in the world (Wallpaper/Lock screen), no-one would ever say they wouldn’t like things even simpler, right? Also, how about being able to set these things from a viewmodel in a PCL?

The Solution

So once you’ve added the beta for the Cimbalino Toolkit with UWP support, you’ll want to go straight for the PersonalizationService (yes, it has a z, shut up!). This is a really simple service that contains two methods and a property.

Before you try and set either the lock screen or the wallpaper, you’ll need to check if this is supported (cunningly, the IsSupported property).

Both the SetLockScreenImageAsync() and SetWallpaperImageAsync() methods can be used in the same way: you pass in a path to where the image lives (it has to live locally, you can’t use external images), and you can tell the service whether the image is part of the application package (ie, came as part of your app), or if it’s been saved to a part of the app’s storage area.

private async void UIElement_OnTapped(object sender, TappedRoutedEventArgs e)
{
    var personalisation = new PersonalizationService();
    if (personalisation.IsSupported)
    {
        await personalisation.SetWallpaperImageAsync("ms-appx:///Assets/Wallpaper.jpg", true);
    }
}

The result of that is as follows:

image

Full sample of this can be found on GitHub: https://github.com/Ferret-Labs/MetroNuggetsCode/tree/master/PersonalisationService

SL


Universal Windows Apps, AppBars and Custom Colours

$
0
0

In your Universal app, you may want to have AppBars that have different colours from the default theme colours, which is understandable if you want to add your own branding to it. But when you set the Foreground/Background colours, you may end up with behaviour you weren’t fully expecting.

The Problem

Consider the following xaml:

    <Page.BottomAppBar>
        <CommandBar Background="Blue"
                    Foreground="White">
            <CommandBar.PrimaryCommands>
                <AppBarButton Label="settings"
                              Icon="Setting"
                              Foreground="White"/>
            </CommandBar.PrimaryCommands>
            <CommandBar.SecondaryCommands>
                <AppBarButton Label="about"
                              Foreground="White"/>
            </CommandBar.SecondaryCommands>
        </CommandBar>
    </Page.BottomAppBar>

You can see here that we have an AppBar with both primary and secondary commands. When you run the app, you’ll end up with a Window that looks like this:

Desktop:
AppBarNotOpen

Phone:
PhoneAppBarNotOpen

So this is the PrimaryCommands, all looking good, we tap the ellipsis, and this is where we get the unexpected behaviour:

Desktop:
AppBarOpen

Phone:
PhoneAppBarOpen

As you can see (just), the SecondaryCommands area of the CommandBar has not respected the colours you set against it, it uses whatever your app’s theme is set as.

The Solution

Tucked away in MSDN, there’s a little sentence that says: “The default overflow menu is styled to be distinct from the bar. You can adjust the styling by setting the CommandBarOverflowPresenterStyle property to a Style that targets the CommandBarOverflowPresenter.” There is nothing to state what the effects of not doing this are (basically what you see above).

What this means is you just need to add a little bit of extra xaml to enable this in your appbar:

    <Page.BottomAppBar>
        <CommandBar Background="Blue"
                    Foreground="White">
            <CommandBar.CommandBarOverflowPresenterStyle>
                <Style TargetType="CommandBarOverflowPresenter">
                    <Setter Property="Background"
                            Value="Blue" />
                </Style>
            </CommandBar.CommandBarOverflowPresenterStyle>
            <CommandBar.PrimaryCommands>
                <AppBarButton Label="settings"
                              Icon="Setting"
                              Foreground="White"/>
            </CommandBar.PrimaryCommands>
            <CommandBar.SecondaryCommands>
                <AppBarButton Label="about"
                              Foreground="White"/>
            </CommandBar.SecondaryCommands>
        </CommandBar>
    </Page.BottomAppBar>

Note the extra CommandBarOverflowPresenterStyle (a mouthful, right!). Which gives the result:

Desktop:
AppBarFixedOpen

Phone:
PhoneFixedAppBarOpen

So there you get the expected behaviour (certainly expected on phone).

I’m told that the reason for this is to prevent the “L” shape you see in the fixed desktop version, but at least you know there is a way to make it like that should your design dictate it.

Source: https://github.com/Ferret-Labs/MetroNuggetsCode/tree/master/AppBarCustomColour

SL


Creating a Weather App Style Adaptive Tile

$
0
0

In Windows 10, we’ve seen apps that look to have different tile faces and they cycle between those tiles. It’s a really nice effect and can be a very powerful thing for your app to use, it allows you to present more data to the user without having to have your tile all cramped. A good example of this would be a weather app where you might want to allow the user to show the weather for different places. So, how do you go about creating a tile like this?

The Solution

Using my AdaptiveTileExtensions, this is actually rather simple.

Let’s say we want to make a tile that looks like this:
WeatherTile

It’s a fairly common sort of tile for a weather app, how would you go about doing that.

        private static TileBinding CreateTile(TemplateType size, Place place, int limit = 10)
        {
            var tileBinding = TileBinding.Create(size);
            tileBinding.DisplayName = place.PlaceName;
            tileBinding.Branding = Branding.Name;
            tileBinding.OverlayOpacity = 20;

            tileBinding.Add(new TileImage(ImagePlacement.Background) {Source = string.Format(WallpaperUriTemplate, place.OverallForecast)});

            foreach (var forecast in place.Forecast.Take(limit))
            {
                var subGroup = new SubGroup {Width = 1};
                subGroup.AddText(new Text(forecast.Day) {Alignment = Alignment.Center});
                subGroup.AddImage(new TileImage(ImagePlacement.Inline) {RemoveMargin = true, Source = string.Format(UriTemplate, forecast.Forecast)});
                subGroup.AddText(new Text($"{forecast.TemperatureHigh}°") {Alignment = Alignment.Center});
                subGroup.AddText(new Text($"{forecast.TemperatureLow}°") {Alignment = Alignment.Center, Style = TextStyle.Caption, IsSubtleStyle = true});

                tileBinding.AddSubgroup(subGroup);
            }
            return tileBinding;
        }

As you can see, for a starter, no xml! We basically take each forecast bit of information and construct the text and images accordingly. Note the Width=1 when creating the SubGroups, this is what allows you to have each subgroup taking up equal width.

What about creating the tile itself:

        private void WeatherTilesButtonTapped(object sender, TappedRoutedEventArgs e)
        {
            var updater = TileUpdateManager.CreateTileUpdaterForApplication();
            updater.Clear();
            updater.EnableNotificationQueue(true);


            foreach (var place in _places)
            {
                var tile = AdaptiveTile.CreateTile();
                var wideTile = CreateTile(TemplateType.TileWide, place);
                var mediumTile = CreateTile(TemplateType.TileMedium, place, 2);

                tile.Tiles.Add(wideTile);
                tile.Tiles.Add(mediumTile);

                var notification = tile.GetNotification();

                updater.Update(notification);
            }
        }

Now, for each tile face you want to show, that needs to be its own tile, you do not add multiple versions for each tile size. So in the code above, for each place we’re wanting to display a tile face for, we are creating the tile, then adding the wide tile UI and the medium tile UI to it and calling Update() on the app’s main TileUpdater.

Now, the key part to all of this, for displaying multiple faces on your tile, is you have to call EnableNotificationQueue() so that each time we call Update() we add the tile to the queue. If you don’t do this, then each time you call Update(), only the most recent tile will show.

And there you have it, you’ll end up with a tile that slides up and changes its face:
WeatherTileChanging

Full code and working app can be found at https://github.com/Ferret-Labs/MetroNuggetsCode/tree/master/NiceLookingTiles

SL


Dealing with Right-to-Left Languages, Things to Consider

$
0
0

Localising your apps can be hard, whether it’s finding the funds to get all your resources localised, or finding community members who will help you do it, it’s never easy. Those levels of difficulty can also be increased when you start to consider right-to-left languages, such as Arabic, or Hebrew, because it’s not just a question of adding those languages and you’re done. Far from it, in fact. Not only do you have to write extra code just to enable right-to-left, there are other practical matters that you may need to consider for your app’s design. Why? Because with right-to-left languages, the whole UI gets mirrored. Let’s look at some of those things you may need to think about.

Enabling Right-to-Left

First off, I mentioned you need to actually write some extra code to enable right-to-left; this is fairly straight forward code.

string resourceFlowDirection = ResourceContext.GetForCurrentView().QualifierValues["LayoutDirection"];
RootFrame.FlowDirection = resourceFlowDirection == "RTL" ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;

That’s all you need to determine if you’re going to have to enable right-to-left. Some notes about this though:

  • If you use any additional frames within your application (be it in dialog windows, share windows, etc), then you will need to make sure you set the FlowDirection on those too otherwise they won’t get the effects.
  • If you haven’t added any right-to-left languages to your app’s manifest, then these checks will never return true and so your app will always been in the default left-to-right state.

Images

By default, all Images will inherit the FlowDirection of its parents, which will nearly always have come down from the frame. What this means is all Images will also be mirrored. You will want to make sure that any images that are mirrored are correctly so; for example, if you have user submitted images, you will want them to display normally and not mirrored, so you need to explicitly set the FlowDirection to be LeftToRight.

FontIcons

By default, these do not mirror in your UI, so if you were expecting them to, be sure to check that this behaviour is what you need. If you do need them to mirror, then you must set MirroredWhenRightToLeft=”true” on any FontIcons you do want to be mirrored.

Left is Right, Right is Left

What on earth do I mean by that? With the UI being mirrored, it means any X co-ordinates you’re using in your app may not be quite what you’re expecting. When you look at the screen, what you get as 0 for your X co-ordinate will be on the right-hand side of your screen, not the left. If you have any animations or code for moving things left/right based on where a user’s finger is dragging things, then you need to take this into account. Moving your finger from the right side of the screen to the left, will increase your X co-ordinate in a right-to-left world. By not taking this into account, you can end up either placing things in the incorrect side of the screen, or dragging things move in the opposite direction to which the finger is moving.

RelativePanels

What about using RelativePanel and things like RelativePanel.AlignLeftWithPanel or AlignLeftWith attached properties? Well those just get mirrored as normal, there is nothing you need to do for this.

SL


Device Family Views: Some Continuum Advice

$
0
0

There are a number of blog posts, that show off a new feature in Windows 10 development call xaml views, that allow you to have a different xaml file for the same page depending on the device family (a great one here by Morten). There may be genuine reasons where going for an adaptive approach might not be right for your app depending on the design constraints of your app, in which case it makes perfect sense that you’d want device specific views.

Coming soon with the new Lumia devices is a nice feature called Continuum, which allows you to effectively use your phone as a PC, where you can connect it to a monitor, and use a mouse and keyboard with it, and really shows to highlight the universal aspect of Universal Apps as you effectively then have a desktop UI that you can use. So using a desktop on a mobile, what could go wrong?

Turns out, your UI could go wrong. Why? Because although you’re seeing a desktop UI, the OS is still reporting to your app that it’s a mobile device, which means it will use any mobile specific views/code that you may be using. This means that although you have this gorgeous desktop UI, when a user uses your app in Continuum, all they will see is the [still gorgeous, I’m sure] mobile UI, but not the desktop one. So how do you get around this?

The Solution

The funny answer is you actually have to go back to adaptive triggers, but not based on height/width, instead on device family.

My recommended steps are as follows:

  • Remove the xaml from your device family specific views and put them into UserControls
  • Use a device family based custom Windows State Trigger (like Morten’s one here, he gets everywhere!)
  • You may want to customise the aforementioned state trigger to use the new API in 10563 and above, which is the DisplayInformation.DiagonalSizeInInches (call it using DisplayInformation.GetForCurrentView().DiagonalSizeInInches) and check for anything over 6 for desktop, as the biggest Windows phones right now are 6 inches.
  • Set both UserControls to Visibility.Collapsed in your page, and use x:DeferLoadingStrategy=”Lazy” so you’re not trying to load either: both UIs, or the wrong UI for the one you’re wanting. In other words, you don’t want to start with the mobile one showing in case the app is launched in Continuum, similarly, don’t start with the desktop in case it’s started on the phone.

What about Xbox One/IoT?

Since neither of these have any interaction with Continuum, you can continue to have device specific views for both of those without any negative impact.

I’ll concede this solution isn’t the most elegant, and it would be better if the device family could be reported as Desktop when being run in Continuum, because the platform *must* know, right? But as it stands, you just can’t rely on it right now.

SL



Got Unexpected, Extra Languages in Your UWP Store Submission?

$
0
0

If you’ve tried submitting a Windows 10 app to the store recently, you may have come across a problem where it’s asking you to enter store information for a language your app isn’t configured to support (in my case, I had an app that was en-GB, but it was requesting details for en-US, too). This can be frustrating because you probably don’t want to have to create the assets and store information for that extra language; so why is it appearing?

The Solution

This is a bug with Visual Studio 2015 when it’s building your app package and occurs when you have PCLs that have a different default language than app being built. In my case, I had MVVM Light, whose default language was en-US.

Fortunately, there is a workaround until VS2015 gets this fixed, open the app’s project file, and add the following to the first PropertyGroup in there:

<SkipIntermediatePriGenerationForResourceFiles>false</SkipIntermediatePriGenerationForResourceFiles>

Now when you build your app package, you should only see the expected number of languages when you submit your app to the store.

SL


Using WebAccountProvider with Facebook on Windows 10 Mobile

$
0
0

For a while now, there have been a few ways for developers to allow a user to sign into Facebook:

  • They could use the WebAuthenticationBroker, which launched a hosted window the user could enter their details in;
  • They could use their own hosted WebView (WebBrowser on Silverlight) and send the user to the same place as the WebAuthenticationBroker and handle the navigations themselves;
  • They could use the Facebook Client SDK (in Silverlight), or the Windows SDK for Facebook (in Universal apps);
  • Manually create the URI scheme that would launch the Facebook app and have the app do the authentication for you.

With Windows 10, there’s a new way for developers to be able to authenticate their users, and that’s the WebAccountProvider. This allows account providers (like Facebook) to provide authentication using their Windows 10 app. Using this approach would mean your users would never have to leave the comfort of your app to get authenticated.

So what does all this mean? What is WebAccountProvider? It’s possible, in Windows 10, for apps to allow developers to explicitly use them as an authentication provider, without having to use URI schemes and callbacks to be set up by the calling app. The difference between this approach and the URI/Callback approach is this can be done silently so the user can potentially never leave your app but still get successfully authenticated.

IMPORTANT NOTE

All of this blog post is based on the current Windows 10 Facebook beta that came out recently. If you submit a Windows 10 app to the store before this version leaves beta, this code will not work as the user will likely be using the non-beta Facebook app. If you only depend on this approach, then your users will not be able to authenticate with Facebook, so it’s important to have some fallback methods.

This is now available in the non-beta version of Facebook for Windows 10 too, so will work for anyone who has updated their app.

Check for Account Providers

The first thing you need to do is see if there is a provider available for the service you’re looking to use; if there’s no app provider, then you should have a fallback method to use.

// Check whether there is an app for the provider we want to use (facebook)
var provider = await WebAuthenticationCoreManager.FindAccountProviderAsync("https://www.facebook.com");

To get the provider, you give FindAccountProviderAsync an id for that provider; in Facebook’s case, that’s their website address (including https). If the Facebook app is installed, this will return a provider, and if the app is not installed, this will be null and you should proceed to whatever fallback method you’re choosing to use.

Check Silently First

The first check you’ll want to do is a silent call to that provider to see whether it has any account details that have already been stored by the app. So we create our WebTokenRequest. For this sample, I’ll use the basic public_profile scope, but you can use whatever set of permissions you need for your app. These would be included as part of the request, and if you have more than one scope for your app, include them as a comma separated string (eg, “public_profile,email,user_friends”).

var request = new WebTokenRequest(provider, "public_profile", "");

// We need to add the redirect uri so that the facebook app knows it's actually us.
// This will use the store id you assigned in your facebook developer portal
request.Properties.Add("redirect_uri", "msft-");

And then we make our silent call to the provider using GetTokenSilentlyAsync

result = await WebAuthenticationCoreManager.GetTokenSilentlyAsync(request);

Once we have the result, we can check whether we have our credentials, whether the user cancelled, the process encountered an error, or whether there is some user interaction required. We do this by checking the result’s ResponseStatus property.

User Interaction Required

If your result has come back with a status of UserInteractionRequired, this means that there were no stored credentials for this provider and we need to make a subsequent call to RequestTokenAsync.

result = await WebAuthenticationCoreManager.RequestTokenAsync(request);

And again, once you have your result, you can check the ResponseStatus to see how next to proceed.

Extracting the Token

Once you have got a Success status, then you can get the user’s access token and their Facebook username

var tokenResponse = response.ResponseData[0];
var accessToken = tokenResponse?.Token;
var username = tokenResponse?.WebAccount?.UserName;

And that’s it.

Fallback Methods

As noted throughout this post, it’s good practice to have at least one fallback method in case the user doesn’t have the Windows 10 Facebook app installed. The different fallback methods would be:

  1. The URI Scheme (be sure to use FindUriSchemeHandlersAsync to check for “fbconnect”). If that fails, then;
  2. WebAuthenticationBroker

Source Code

There is a working sample on Github.

Windows SDK for Facebook

I should imagine the Windows SDK for Facebook released in the Summer will be getting an update to also support this authentication approach.

SL






Latest Images