0 Comments

Problem

When you create a Universal Windows Platform app and run it in Windows 10, you may notice that the logo displayed on taskbar is not full size.

For example, if you have this beautiful 24x24 logo:

image

And you set that as your taskbar logo:

image

And then run the app, you’ll notice that it looks out of place:

image

Two problems:

  1. The logo is not full size
  2. The remaining space is filled with your accent color

Solution

The problem can be fixed by renaming the logo file. When you set the logo through Package.appxmanifest’s designer, the asset will receive file name Square44x44Logo.targetsize-24.png:

image

Just rename the file to Square44x44Logo.targetsize-24_altform-unplated.png:

image

And now when you ran the app, you should see that your icon fits the taskbar nicely:

image

0 Comments

imageThis post will show you how to use repositioning to create a responsive layout for your XAML Universal Windows app (UWP) using Grid and AdaptiveTrigger.

Background

With Windows 10 and its UWP stack, making your app look nice on both mobile and desktop is one of the core requirements. The Responsive design 101 for Universal Windows Platform (UWP) apps guide on MSDN outlines six different ways for responsive design:

  • Reposition
  • Resize
  • Reflow
  • Reveal
  • Replace
  • Re-architect

In this post we’ll use the familiar Grid-control with the AdaptiveTrigger to reposition our app’s content. On desktops and tablets the app will use 2-column layout. On mobile devices (or when user resizes the app to have a small window) the second column drops under the first one.

AdaptiveTrigger

AdaptiveTrigger is a new addition in Windows 10. You can use AdaptiveTrigger to automatically change the VisualState when the app’s width or height changes. For example the following Channel9-video contains good information about the AdaptiveTrigger.

The code

Here’s out app’s simple layout:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" x:Name="MainGrid">

        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <Grid x:Name="FirstGrid" Grid.Column="0" Grid.Row="0" Background="#0078d7" />
        <Grid x:Name="SecondGrid" Grid.Column="1" Grid.Row="0" Background="#107C10" />

    </Grid>

Without any VisualStates or AdaptiveTriggers, the app will look the same on all screen sizes:

image

But what we want is to reposition our SecondGrid under the FirstGridon mobile devices. To do this, we need to change the Grid.Column and Grid.Row of the SecondGrid:

                        <Setter Target="SecondGrid.(Grid.Column)" Value="0"/>
                        <Setter Target="SecondGrid.(Grid.Row)" Value="1"/>

Also, there’s no need for two columns so we modify the MainGrid for our needs:

                        <Setter Target="MainGrid.RowDefinitions[1].Height" Value="*"/>
                        <Setter Target="MainGrid.ColumnDefinitions[1].Width" Value="auto"/>

Last thing we do is change the margins to make things little prettier:

                        <Setter Target="MainGrid.Margin" Value="12"/>
                        <Setter Target="FirstGrid.Margin" Value="0 0 0 6"/>
                        <Setter Target="SecondGrid.Margin" Value="0 6 0 0"/>

And that’s it. Here’s all the VisualState changes combined. First the WideState (2-column layout):

                        <Setter Target="MainGrid.Margin" Value="24"/>
                        <Setter Target="MainGrid.RowDefinitions[1].Height" Value="auto"/>
                        <Setter Target="MainGrid.ColumnDefinitions[1].Width" Value="*"/>
                        <Setter Target="FirstGrid.Margin" Value="0 0 6 0"/>
                        <Setter Target="SecondGrid.Margin" Value="6 0 0 0"/>
                        <Setter Target="SecondGrid.(Grid.Column)" Value="1"/>
                        <Setter Target="SecondGrid.(Grid.Row)" Value="0"/>

And then the NarrowState (mobile layout):

                        <Setter Target="MainGrid.Margin" Value="12"/>
                        <Setter Target="FirstGrid.Margin" Value="0 0 0 6"/>
                        <Setter Target="SecondGrid.Margin" Value="0 6 0 0"/>
                        <Setter Target="MainGrid.RowDefinitions[1].Height" Value="*"/>
                        <Setter Target="MainGrid.ColumnDefinitions[1].Width" Value="auto"/>
                        <Setter Target="SecondGrid.(Grid.Column)" Value="0"/>
                        <Setter Target="SecondGrid.(Grid.Row)" Value="1"/>

With these few lines of XAML we have used repositioning to achieve a nice responsive layout.

image

Download source code

The full source code is available from GitHub.

https://github.com/mikoskinen/UWPResponsiveXAMLLayoutGridAdaptiveTrigger

0 Comments

We’re working with a Windows 8.1 Store App where we need to know the physical screen size of the display. Here’s some simple code which seems to do the trick in most cases:

            var width = Window.Current.Bounds.Width * (int)DisplayProperties.ResolutionScale / 100;
            var height = Window.Current.Bounds.Height * (int)DisplayProperties.ResolutionScale / 100;

            var dpi = DisplayInformation.GetForCurrentView().RawDpiY;

            var screenDiagonal = Math.Sqrt(Math.Pow(width / dpi, 2) +
                        Math.Pow(height / dpi, 2));

            return screenDiagonal.ToString();

Please note that the DPI will return 0 if you have two displays in duplicate mode: http://msdn.microsoft.com/en-us/library/windows/apps/windows.graphics.display.displayinformation.rawdpix

Portable Class Libraries are a great way to share common code between different platforms. But here lies the danger: A portable class library project cannot change the underlying platform.

Here’s a simple explanation of what that means.

Example project

The example application is built for Windows Forms, Windows RT and Windows Phone. The authentication mechanism is identical in every app so that is placed in a Portable Class Library project:

    public class WebTool
    {
        public async Task<string> GetAuthenticationKey()
        {
            var cookieContainer = new CookieContainer();
            var client = new HttpClient(new HttpClientHandler() { CookieContainer = cookieContainer });

            // Authenticate with the service
            await client.GetStringAsync("http://cookietest.api.domain.com/cookie/get");

            // Return the received cookie as authentication key
            var cookieHeader = cookieContainer.GetCookieHeader(new Uri("http://cookietest.api.domain.com/"));

            return cookieHeader;
        }
    }

Using this library doesn’t get easier: Each platform can call it with identical code:

            var webTool = new WebTool();

            var result = await webTool.GetAuthenticationKey();

            if (string.IsNullOrWhiteSpace(result))
                this.Result.Text = "Didn't receive authentication key!";

            else
                this.Result.Text = "Authentication key: " + result;

Few minutes and everything is done, so the testing phase begins.

First, Windows Forms:

image

Then Windows 8:

image

And last but not least, Windows Phone:

image

Uh oh.

Cookies and CookieContainer especially are different beasts in different platforms. Portable Class Library cannot hide that fact.

Have you encountered similar issues when dealing with Portable Class Library projects?

0 Comments

The regional settings still misbehave in Windows 8.1 XAML apps. They misbehaved already in Windows 8 and they continue to misbehave in apps written with a newer WinRT. Some may say that they work as designed. To them I say the design is wrong.

The previous post about this subject contains more info, but here’s a short introduction to the problem.

Scenario:A Finnish users starts my Windows 8 XAML app. The app displays dates and times. The app isn’t localized to any language. I want the app to show the dates and times in Finnish format as that’s how she has configured her regional settings:

The problem:The app doesn’t respect her settings. Instead, all the dates and times are formatted using the US settings:

Capture

Other frameworks: Windows Forms, Console Applications, WPF, Silverlight and ASP.NET all handle this correctly: Dates and times are formatted using the regional settings:

image

The workaround: It’s possible to get the dates and times formatted correctly in WinRT apps. It’s just requires a lot of code. I call this a workaround until the WinRT XAML apps start behaving as they should:

            var usersLanguage = Windows.Globalization.Language.CurrentInputMethodLanguageTag;

            var dateFormatter = new DateTimeFormatter("shortdate", new[] { usersLanguage }).Patterns[0];
            var timeFormatter = new DateTimeFormatter("shorttime", new[] { usersLanguage }).Patterns[0];
            var fullFormatter = new DateTimeFormatter(dateFormatter + " " + timeFormatter);

            this.MyDate.Text = fullFormatter.Format(DateTime.Now);

image

Update 4.7.2013:

It seems I can get the behavior similar to Silverlight and other frameworks by setting the Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride on application startup (App.xaml.cs). For example:

        public App()
        {
            Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = Windows.Globalization.Language.CurrentInputMethodLanguageTag;
            this.InitializeComponent();
            this.Suspending += OnSuspending;
        }