Closed kirsan31 closed 3 years ago
Guys, I am bit confused here :thinking:
@RussKie why this is a bug? This is by WinForms design:
NOTE: This logic is to keep minimized MDI children anchored to the bottom left of the client area, normally they are anchored to the top right which just looks weird!
@dreddy-work And I don't understand how it's related to HDPI?
@dreddy-work And I don't understand how it's related to HDPI?
From the attached images, we were looking at the nature of minimized MDI windows location being constant after windows resolution change that resized Form window to changed resolution/DPI. This is something that need to be handled when DPI changes. Correct us if we are not reading it right.
@dreddy-work yes you are not reading this right :) This is absolutely not related to HDPI. As I wrote, this is WinForms decision - override default anchor (TopLeft) of minimized child mdi windows with (BottomLeft). I made a video with difference in WinForms (Bottom-Left anchor) vs MFC (Top-Left anchor):
@dreddy-work yes you are not reading this right :) This is absolutely not related to HDPI. As I wrote, this is WinForms decision - override default anchor (TopLeft) of minimized child mdi windows with (BottomLeft). I made a video with difference in WinForms (Bottom-Left anchor) vs MFC (Top-Left anchor):
mdi.mp4
Thanks for the GIF. Earlier images attached were not clear enough to understand the expected behavior around anchoring of minimized MDI windows. Did you try bypassing ‘Setbounds*’ method?
Did you try bypassing ‘Setbounds*’ method?
Your mean SetBoundsCore
of MDIClient
? If yes, then - no, not directly. We are doing revert move in OnResize
:
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
if (_OldHeight != -1 && _OldHeight != this.Height)
{
int yDelta = _OldHeight - this.Height;
foreach (var child in ChildrenW)
{
if (child.IsHandleCreated && child.WindowState == FormWindowState.Minimized && child.Visible)
{
WinApi.User32.GetWindowPlacement(child.Handle, out WinApi.User32.WINDOWPLACEMENT wp);
wp.ptMinPosition.Y += yDelta;
wp.flags = WinApi.User32.WPF.SETMINPOSITION;
WinApi.User32.SetWindowPlacement(child.Handle, ref wp);
}
}
}
_OldHeight = this.Height;
}
And it's work well, except that this is a bit overhead :roll_eyes:
Yes. Wanted to check as comments around that code was saying the default behavior was top-right anchored and I observed MFC app was doing top-left.
Yes. Wanted to check as comments around that code was saying the default behavior was top-right anchored and I observed MFC app was doing top-left.
Oh I ever didn't notice that :) Yes, It's typo in comment - Left
everywhere.
I doubt that we can change the default behavior. Perhaps a property that enables the ability to set this. If someone has a proposal for how this might be done we'd be happy to consider it. I'll mark as up for grabs, but move it out to future.
@merriemcgaw
If someone has a proposal for how this might be done we'd be happy to consider it.
The exact proposal in the first post ;)
We are looking for someone to propose (and implement) an API that would enable this to happen. It has to go through the full API review process, and we can help a bit with that. But it looks like there are more urgent fires to fight for .NET 6 so it doesn't look like we will have the resources to enable this feature just yet. If the community can, that would be something we'd totally take.
Ok, lets try this slow way.
We need to add bool
property to Form
class, let it be MdiChildrenMinimizedAnchorTop
.
Draft API Proposal
namespace System.Windows.Forms
{
public partial class Form : ContainerControl
{
/// <summary>
/// true - anchoring minimized MDI children to the TopLeft of the parent form (windows default). false - anchoring minimized MDI children to the BottomLeft of the parent form (WinForms default)
/// </summary>
[SRCategory(nameof(SR.CatWindowStyle))]
[DefaultValue(false)]
[SRDescription(nameof(SR.FormMdiChildrenMinimizedAnchorTopDescr))]
public bool MdiChildrenMinimizedAnchorTop { get; set; }
}
}
To do.
SetBoundsCore
method of MdiClient
class and do PR.Once we've figured out the name of the property and description (we can get the translations automatically) we may be able to bring this through the API review process. Can you copy the content above to the first comment in the issue? That's what the API folks look for.
@merriemcgaw
Can you copy the content above to the first comment in the issue? That's what the API folks look for.
Done.
I've created draft PR #5221. May be it's speed up things a bit? :)
@dreddy-work can you start a thread with @terrajobst to get approval for this API change? Let's get that started while @kirsan31 is kindly coding the new API so we know we can get this in .NET 6 for sure
Sure.
Easiest is to file an issue in the winforms repo, put it in the 6.0.0 milestone, mark it as blocking and api-ready-for-review. We'll look at it first thing Tuesday morning then.
MdiChildren
namespace System.Windows.Forms
{
public partial class Form
{
[SRCategory(nameof(SR.CatWindowStyle))]
[DefaultValue(true)]
[SRDescription(nameof(SR.FormMdiChildrenMinimizedAnchorTopDescr))]
public bool MdiChildrenMinimizedAnchorBottom { get; set; }
}
}
[SRDescription(nameof(SR.FormMdiChildrenMinimizedAnchorTopDescr))]
[SRDescription(nameof(SR.FormMdiChildrenMinimizedAnchorBottomDescr))]
Should be in the same property grid category as MdiChildren
All of them are in CatWindowStyle.
@kirsan31 Verified this function with .NET SDK 6.0.100-rc.1.21424.1, the results MdiChildrenMinimizedAnchorBottom=False and MdiChildrenMinimizedAnchorBottom=True are the same. the result as below.
This is my test project: WinFormsApp2.zip, What else needs to be set up in this project?
@Jenna-Zheng Sadly I can't fully verify this :( I've downloaded and installed this sdk dotnet-sdk-6.0.100-rc.1.21426.23-win-x64.exe from here.
Your project build fine, but when I run it, it's fail with:
😲
Win10 20H2. dotnet --info:
I think it's something related to WinFormsApp2.runtimeconfig.json
:
{
"runtimeOptions": {
"tfm": "net6.0",
"frameworks": [
{
"name": "Microsoft.NETCore.App",
"version": "6.0.0-rc.1.21425.15"
},
{
"name": "Microsoft.WindowsDesktop.App",
"version": "6.0.0-rc.1.21426.11"
}
]
}
}
But changing it to:
{
"runtimeOptions": {
"tfm": "net6.0",
"framework": {
"name": "Microsoft.WindowsDesktop.App",
"version": "6.0.0"
}
}
}
have no affect :(
Beside this.
System.Windows.Forms.dll
(6.0.21.42604) from sdk in ILSpay and my code is there. And if MdiChildrenMinimizedAnchorBottom == true
all must work as before:
protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
{
if (base.IsHandleCreated)
{
Form obj = ParentInternal as Form;
if (obj == null || obj.MdiChildrenMinimizedAnchorBottom)
{
Control parentInternal = ParentInternal;
if (parentInternal == null || parentInternal.Site?.DesignMode != true)
{
...
return;
}
}
}
base.SetBoundsCore(x, y, width, height, specified);
}
MdiChildrenMinimizedAnchorBottom
in VS:So, my guess is: something build wrong in this rc, or something is broken in other place...
@kirsan31 you can use this link https://vsdrop.corp.microsoft.com/file/v1/Products/DevDiv/VS/be0dbbd8fb834a2f05bd0d926c1f414a0ed97045/e9ec17f0-3ec5-0d17-956b-202ebb9e08a4;bootstrappers/Enterprise/vs_enterprise.exe to install VS, dotnet-sdk-rc.1.21424.1-win-x64.exe
have been insert into this VS.
@kirsan31 you can use this link https://vsdrop.corp.microsoft.com/file/v1/Products/DevDiv/VS/be0dbbd8fb834a2f05bd0d926c1f414a0ed97045/e9ec17f0-3ec5-0d17-956b-202ebb9e08a4;bootstrappers/Enterprise/vs_enterprise.exe to install VS,
dotnet-sdk-rc.1.21424.1-win-x64.exe
have been insert into this VS.
Thanks @Jenna-Zheng but I can't open your link (DNS_PROBE_FINISHED_NXDOMAIN) :( But any way I will not install other VS instance on my machine :( last time I done it (during this PR :)) this completely broke my working VS2019 :(
Verified this issue with .NET 5.0&3.1, it is still reproducing, verified it with .NET 6.0, it is fixed Whether mdichildrenminized anchor bottom is set to false or true, the result is the same. Is this expected? .NET 5.0 & 3.1
.NET 6.0 MdiChildrenMinimizedAnchorBottom=False and MdiChildrenMinimizedAnchorBottom=True
With latest SDK from https://github.com/dotnet/installer. I have no error as above, but:
So, we defiantly need some working sdk here...
This is a known SDK issue, which was fixed. But the fix hasn't apparently flown through.
Installing latest RC1 from here https://github.com/dotnet/installer should not have this issue. RC2 build, investigating.
@dreddy-work
Installing latest RC1 from here https://github.com/dotnet/installer should not have this issue. RC2 build did not get this fix yet.
RC1:
RC2:
Verified this function with .NET SDK 6.0.100-rc.1.21424.1 and .NET SDK 6.0.100-rc.2.21429.3now, it is fixed that Customer can use MdiChildrenMinimizedAnchorBottom to revert for Windows default behavior. MdiChildrenMinimizedAnchorBottom=True
MdiChildrenMinimizedAnchorBottom=False
Is your feature request related to a problem? Please describe. WinForms override standard MDI behavior without option to use original one. It's lead to all child windows layout (with minimized windows) are mess up after main window resize. This can happened after simple resize, or after resolution changed (for example if your connect by rdp from other device), etc... before res. change (left - WinForms, right - MFC): after res. change (left - WinForms, right - MFC):
Video:
https://user-images.githubusercontent.com/17767561/112429754-26a14200-8d4e-11eb-83d5-393626ad23b6.mp4
For now we need to manually revert this move (with same technique) after each resize :(
Draft API Proposal
We need to add bool property to
Form
class, let it beMdiChildrenMinimizedAnchorTop
:To do.
SetBoundsCore
method ofMdiClient
class and do PR.