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

Docking is not working properly #640

Open
ak-gr8 opened this issue Nov 17, 2020 · 6 comments
Open

Docking is not working properly #640

ak-gr8 opened this issue Nov 17, 2020 · 6 comments

Comments

@ak-gr8
Copy link

ak-gr8 commented Nov 17, 2020

We've found the following problem:
Imagine that you have a laptop and a second monitor. The windows (10) has the "Scale and Layout" setting. Usually this setting for laptop monitor has 125% and 100% for second monitor. Run the app on one monitor and then move it to the second one. Then use "Drag & Drop" to try to dock any panel in a different place. You will find that it cannot be done. Dockpanelsuite calculates coordinates incorrectly.
ps: It was not easy to figure out why the problem is happening. You can easy to reproduce on multiple monitors. Just set a different scale for each monitor.

@ndepend
Copy link

ndepend commented Feb 16, 2021

The cause of this bug is this call to Bounds = SystemInformation.VirtualScreen; in DockIndicator here.

                public override void Show(bool bActivate)
                {
                    base.Show(bActivate);
                    Bounds = SystemInformation.VirtualScreen;
                    RefreshChanges();
                }

Because of that the DockIndicator form now spawns all monitors with various DPI, but a form can only know about a single monitor DPI, hence the bug.

To fix it one needs to comment Bounds = SystemInformation.VirtualScreen; and update the DockIndicator form's bounds at the beginning of RefreshChanges() here:

                private void RefreshChanges() {
                    var allScreens = Screen.AllScreens;
                    var mousePos = Control.MousePosition;
                    foreach (var screen in allScreens) {
                       if (screen.Bounds.Contains(mousePos)) {
                         Bounds = screen.Bounds;
                       }
                    }
                    Region region = new Region(Rectangle.Empty);
                    ...

This works because when the mouse is moved over a panel on a screen (B) different than the screen (A) on which the dock-indicator was initiated by a mouse left-button-down, RefreshChanges() is called. Thus the bounds of the DockIndicator form are actualized to the bounds of screen (B). As a consequence the DockIndicator form's DPI value is implicitly set to the DPI value of screen (B).

Note1: This fix works and has been tested on a winforms application with an app.manifest that defines <dpiAware>True</dpiAware> but doesn't define the <dpiAwareness>. Changing <dpiAwareness> might have an impact on the bounds of screen returned by Screen.AllScreens and mouse location returned by Control.MousePosition.

app.manifest file:
...
  <asmv3:application>
    <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
      <dpiAware>True</dpiAware>
    </asmv3:windowsSettings>
  </asmv3:application>

Note2: In the app.manifest context described in Note1, when creating a new FloatingWindow by dragging it from a screen (A) to a screen (B) with different (A) and (B) DPI values, the floating-window needs to be re-located to properly adapts to the DPI of screen (B). This secondary problem can be fixed by slightly changing the new FloatingWindow location from within a new a OnLoad() handler here.

  protected override void OnLoad(EventArgs e) {
     this.Location = new Point(this.Location.X + 1, this.Location.Y);
     base.OnLoad(e);
  }

lextm added a commit that referenced this issue Feb 21, 2021
@EFeru
Copy link

EFeru commented Aug 19, 2021

@lextm @psmacchia do you know if this issue fixed?

I have the same problem with my application if my screen is scaled to 125%. The docking points are displayed incorrectly, but the mouse position is correct (somwhere in the middle as expected). See pictures below.

Edit: Short update, the issue happens only if multiple monitors are connected to the computer, from which at least one monitor is not in 100% scale. If single monitor is used it is working correctly, even in 125% scale.

Incorrect positioning of the docking points:
image

Mouse position is correctly calculated (somewhere in the middle as expected):
image

@nsdrussell
Copy link

nsdrussell commented Aug 19, 2021

@EmanuelFeru this issue was never fixed, see this issue. I found that the Krypton Toolkit works very well for Windows Forms docking with display scaling above 100%, I'd recommend it.

@EFeru
Copy link

EFeru commented Aug 19, 2021

@nsdrussell thanks for the quick answer. I found that the issue happens only if multiple monitors are connected to the computer, from which at least one monitor is not in 100% scale. If single monitor is used it is working correctly, even in 125% scale.

What is Krypton Toolkit? Sorry first time I hear about it. Is it also a docking system? Yes, I need it for WinForms.

@nsdrussell
Copy link

nsdrussell commented Aug 19, 2021

@EmanuelFeru It is a C# library to be used with Windows Forms. One of the components is a good docking system. Have a look at this for examples of docking with it.

@EFeru
Copy link

EFeru commented Aug 19, 2021

Wow, I just tryied it. That works very well... why didn't I find this 3 months ago. Now everything is coupled to dockpanelsuite. It took me a lot of effort to save and restore the docking system created by the user. In krypton this looks much more intuitive with persistence.

Not to mention the tab system in Krypton looks so much better, because the default tabControl in Winforms is so bad, no customization what so ever.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants