Some wpf windows do not scale to DPI when opened from a readingpane

Add-in Express™ Support Service
That's what is more important than anything else

Some wpf windows do not scale to DPI when opened from a readingpane
 
develop_centron




Posts: 1
Joined: 2015-10-13
Hello,

we have a problem in our Addin using C#/WPF - one specific dialogwindow, opened from a sidebar/readingpane, does not scale according to dpi while others do.

User added an image

Our setup is as follows: we have an addinexpress ADXOlForm which contains a single elementhost. This elementhost hosts a single WPF usercontrol, which then hosts several usercontrols with different controls. In one of these subusercontrols we have a Button/ICommand calling a windowmanager that then creates the window as a dialog (with a usercontrol containing the actual window contents).
The window opens as expected, but does not scale according to DPI. Opening the same view from a button in a (addinexpress) ribbon results in it scaling to DPI. Curiously, there's another button/ICommand opening a different window which scales properly.

Additionally we use async/await (with an async command implementation) so it might also be a threading problem. We don't have any DPI related settings set (i.e. DPIAwareness), but WPF should have that by default and every other view scales as expected.

The user has a 4k monitor with an updated windows 10. I was able to reproduce this issue by scaling a monitor differently, also on windows 10 (19041.867).
Addin express has been updated to 9.5.4661 today, but does not fix the problem.

I realize that this might not strictly be a AddinExpress problem/question, but due to the convoluted nature of the problem we cannot pinpoint where to even search for the problem.

Second smaller question: we currently use the following code to scale the contents of the sidebar, is this the best way? It works correctly, but the controls don't react quite properly (buttons have a weird hitbox for example).

private void SideBar_ADXDPIChanged(object sender, ADXDPIChangedEventArgs args)
        {
            try
            {
                Logger.Trace($"DPI changed for sidebar - new values: dpi:'{args.DPI}' dpifactor:'{args.DPIFactor}'");

                // we have to use the this deprecated method here, the new version does something different and doesnt work

#pragma warning disable CS0618 // Type or member is obsolete
                this.Scale(args.DPIFactor);
#pragma warning restore CS0618 // Type or member is obsolete
            }
            catch (Exception e)
            {
                Logger.Error(e, "Error while scaling sidebar");
            }
        }


Greetings and thanks in advance :)
Posted 23 Mar, 2021 08:11:37 Top
Andrei Smolin


Add-in Express team


Posts: 18825
Joined: 2006-05-11
Hello,

Before you create the window, get the thread's DPI context, get the the DPI context of the host application's active window, if they are different set the thread's DPI context. At https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-reference, check GetThreadDpiAwarenessContext(), GetWindowDpiAwarenessContext() and SetThreadDpiAwarenessContext(). You may also need the GetActiveWindow() WinAPI funtion to get the handle of the active window.

Scale() doesn't work well on standard Windows Forms controls (such as check box, option button etc. You should either use custom controls or switch to using WPF.


Andrei Smolin
Add-in Express Team Leader
Posted 23 Mar, 2021 09:32:33 Top