Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a render transform to support dpi scaling in windows forms xaml host #2525

Merged
merged 8 commits into from
Oct 24, 2018

Conversation

lhak
Copy link
Contributor

@lhak lhak commented Oct 3, 2018

Issue: #

PR Type

What kind of change does this PR introduce?

While experimenting with the windows forms xaml host control, I have tried to add at least some dpi scaling support. Applying a render transforms to the UWP content worked surprisingly well and I thought the code might also be useful for others. This pull request adds it directly to the XAML host control.

What is the current behavior?

No dpi scaling support in the XAML host controls

What is the new behavior?

A render transform is added to the UWP XAML content according to the current dpi scaling value. Additionally, a custom panel implementation is used as the root XAML control to transform the values for the layout passes. A new property (DpiScalingRenderTransform) has been added to enable automatic scaling.

Known issues:

  • This code uses win32 apis for getting the current dpi value because the windows forms apis are only supported in newer .net versions than the currently used .net 4.6.2
  • Enabling the DpiScalingRenderTransform property will overwrite any user set render transforms on the provided root XAML element
  • Scaling seems to work mostly fine, but some elements like tooltips do not scale correctly

PR Checklist

Please check if your PR fulfills the following requirements:

  • Tested code with current supported SDKs
  • Docs have been added/updated which fit documentation template. (for bug fixes / features)
  • Sample in sample app has been added / updated (for bug fixes / features)
  • Tests for the changes have been added (for bug fixes / features) (if applicable)
  • Header has been added to all new source files (run build/UpdateHeaders.bat)
  • Contains NO breaking changes

Other information

@nmetulev
Copy link
Contributor

nmetulev commented Oct 3, 2018

@ryalanms should also review this

double dpi = 96.0f;
if (_xamlIslandWindowHandle != IntPtr.Zero)
{
uint windowDpi = SafeNativeMethods.GetDpiForWindow(_xamlIslandWindowHandle);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has this been tested with various DPI modes and manifest settings? We had a lot of problems with web view that ended up requiring a specific version of .NET Framework and specific settings in the manifest to ensure DPI change events were captured and the values were correct

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did some testing with various DPI modes with the scaling property enabled and disabled. There are some winforms specific differences between declaring the dpi mode in app.manifest file or in app.config (for .net 4.7) related to the resizing of the winforms controls but these do not seem to affect the scaling of the XAML content itself. Additionally, recent insider builds apparently now scale the XAML content natively and I have submitted a pull request (#2604) to avoid issues in this case.

Some of my findings for Windows 10 1809 with DpiScalingRenderTransform=true and false and on the latest insider build (18267, with the pull request mentioned above applied):

Not dpi aware app
Windows 1809, DpiScalingRenderTransform=true or false : Scales correctly (surprisingly)
Insider: Sized correctly, but can be blurry

System dpi aware app
Windows 1809, DpiScalingRenderTransform=false : Size is always at 100% + additional scaling when changing dpi, can be blurry in this case
Windows 1809, DpiScalingRenderTransform=true: Scales correctly at initial dpi, but will be blurry when dpi changes dynamically (as the rest of the application)
Insider: same as Windows 1809, DpiScalingRenderTransform=true

Per monitor (V1) aware app
Windows 1809, DpiScalingRenderTransform=false : Size is always 100%, does not scale at all
Windows 1809, DpiScalingRenderTransform=true: Scales correctly at initial dpi, but does not rescale when dpi is changed
Insider: same as Windows 1809 with DpiScalingRenderTransform=true

Per monitor (V2) aware app
Windows 1809, DpiScalingRenderTransform=false : Size is always 100%, does not scale at all
Windows 1809, DpiScalingRenderTransform=true: Scales correctly
Insider: same as Windows 1809 with DpiScalingRenderTransform=true

The remaining issue seems to be with per monitor (v1) dpi aware apps, but even the native scaling in the recent insider builds does not seem to handle this case correctly.

@azchohfi azchohfi merged commit be61690 into CommunityToolkit:master Oct 24, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants