4
votes

I've created my first UWP app. It's a Windows 8.1 UWP app which will help with scheduling courses at my university who's current system is awful. I've been working on it with my Windows 10 desktop computer with a 1080p monitor at default system scaling (100%). I deployed a test build and installed it on my laptop. The laptop is also Windows 10 and 1080p but has a smaller screen so I have system scaling set to 125%. My problem is that instead of this higher scaling factor making my app have bigger features, it does the opposite and shrinks everything in the app.

Here are two screenshots from my laptop when running at different scaling factors. The first is at 100% where everything on the system is too small.

App running at 100% scaling.

Note that the navigation bar on the left is exactly 44 pixels wide, as design. Now in the next screenshot the laptop is running at 125% system scaling (I logged out and in before taking the screenshot so scaling should have updated fully). We should expect that the nav bar be 55 pixels wide.

App running at 125% scaling.

Here you can see that areas in the app actually got smaller than they were before. The nav bar here is about 37 pixels wide compared to the 55 I expected. Is there something I missed in how I must scale a UWP app?

I do not have the entire xaml code with me at the moment as I am on my laptop, but I know that nav bar is part of a grid which looks like this. This grid is the overall grid that is running the app, with the nav bar being the first column.

<Grid x:name="gridOverall">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="44"/>
        <ColumnDefinition Width="200"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    ...

</Grid>

I thought it might have been an enable-scaling option in the app manifest or something but I couldn't find anything like it. I expected issues like this to arise with the images I used as I did not yet include higher resolution options yet, but I didn't expect this to happen with layout elements that are defined in the xaml.

Can anyone shed some insight on what might be going on? This is my first full app and I'm a little lost.

1
UWP scaling on Win10 doesn't work the way you think it does. It pays attention to the physical screen size, not your DPI setting. More here.Hans Passant
No I think I understand it. My laptop monitor is such that it requires 125% system scaling for features to be the correct size. Doing this, the taskbar for instance is the same physical size as on my desktop. If it's at 100% then everything is smaller. My app behaves the same as other things at 100, but at 125 it does not get larger like everything else. I assume I created everything using effective pixels which should scale up by 25% on that setting.Graham

1 Answers

1
votes

Windows 8.1 doesn't have a concept of 125% scaling; it uses 100% / 140% / 180%. The value of DisplayInformation.ResolutionScale will be 100. So it's actually scaled by 80% (100 / 125). And 44 * 0.8 is ~35.

Note: The following is not supported since it relies on reflection and using features of Windows 10 inside a Windows 8.1 app. Use at your own risk.

Here's one way you can try and give people on Windows 10 a better experience with your Windows 8.1 app. I briefly tested it on Windows 10 but you would want to do more thorough testing on Windows 8.1 as well:

private void FixUpScale()
{
  // Need to add a using for System.Reflection;

  var displayInfo = DisplayInformation.GetForCurrentView();
  var displayType = displayInfo.GetType();
  var rawPixelsProperty = displayType.GetRuntimeProperty("RawPixelsPerViewPixel");

  if (rawPixelsProperty != null)
  {
    var realScale = (double)rawPixelsProperty.GetValue(displayInfo);

    // To get to actual Windows 10 scale, we need to convert from 
    // the de-scaled Win8.1 (100/125) back to 100, then up again to
    // the desired scale factor (125). So we get the ratio between the
    // Win8.1 pixels and real pixels, and then square it. 
    var fixupFactor = Math.Pow((double)displayInfo.ResolutionScale /
      realScale / 100, 2);

    Window.Current.Content.RenderTransform = new ScaleTransform
    {
      ScaleX = fixupFactor, 
      ScaleY = fixupFactor 
    };
  }
}