Search code examples
c#wpfscaledpi

WPF Application same size at every system scale (scale independent)


Is there any way to make WPF application get same size at every system scale?

When I change Change size of text, apps and other items in windows system setting from 125% (Recommended) to 100% in a Full-HD screen, My WPF application gets too small. To implement independent system scale application I've wrote a function like this to change scaling of my app back to 125%:

private void ScaleTo125Percents()
{
    // Change scale of window content
    MainContainer.LayoutTransform = new ScaleTransform(1.25, 1.25, 0, 0);
    Width *= 1.25;
    Height *= 1.25;

    // Bring window center screen
    var screenHeight = System.Windows.SystemParameters.PrimaryScreenHeight;
    var screenWidth = System.Windows.SystemParameters.PrimaryScreenWidth;
    Top  = ( screenHeight - Height ) / 2;
    Left = ( screenWidth  - Width )  / 2;
}

But there are conditions to call this function. First of the screen must be Full-HD (There are APIs to check this) and also system scale must be 100% (There is no .NET API to get system scale).

What can I do? Am I doing standard way to make my application system scale independent?

Example of scale independent applications I've seen:

  • Visual Studio 2017 Installer
  • Telegram Desktop

Solution

  • Finally found an answer. First get system DPI scale using one of the options below:

    • Read from registry AppliedDPI dword located in Computer\HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics. Then divide it by 96.
    • Or use this snippet:

      double dpiFactor = System.Windows.PresentationSource.FromVisual(this).CompositionTarget.TransformToDevice.M11;
      

      that returns a value between 1.0 to 2.5

    Then create a config file that holds application settings and set dpiFactor as default scale. If user preferred a custom scale, call this function on window startup:

    private void UserInterfaceCustomScale(double customScale)
    {
        // Change scale of window content
        MainContainer.LayoutTransform = new ScaleTransform(customScale, customScale, 0, 0);
        Width *= customScale;
        Height *= customScale;
    
        // Bring window center screen
        var screenHeight = System.Windows.SystemParameters.PrimaryScreenHeight;
        var screenWidth = System.Windows.SystemParameters.PrimaryScreenWidth;
        Top  = ( screenHeight - Height ) / 2;
        Left = ( screenWidth  - Width )  / 2;
    }