Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

scale

dpi

wpf

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
like image 568
Avestura Avatar asked Jun 21 '17 18:06

Avestura


People also ask

How WPF is resolution independent?

In today's WPF based application development environment we usually come across a requirement to develop a resolution-independent application. What that actually means is that no matter what the resolution of our screen is, our application should behave perfectly.

Is WPF DPI aware?

Windows Presentation Foundation (WPF) applications are by default system DPI-aware.

What is DPI in WPF?

If the current DPI setting is 96 dpi (dots per inch), the WPF units are equivalent to pixels. I.e. A window specified as 96 units high would appear as 1 inch high. If the DPI setting is different, the specified WPF units are scaled by dpi/96 to get the resulting pixel value.


1 Answers

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;
}
like image 166
Avestura Avatar answered Oct 25 '22 08:10

Avestura