1

I'm developing in Winforms with a .NET 4 profile in Visual Studio 2010 at Windows' 100% scaling (96dpi) on Windows 10.

As per the advice from this highly rated answer, I set dpiAware to true in the app.manifest file, set the AutoScaleMode of the main Form to Font, and since I have splitContainers in the Form, but they very unfortunately don't have an AutoScaleMode property in the Wysiwyg Designer, I also have to add these lines to the Designer.cs file:

*.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
*.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);

This ensures that if the user happens to use Windows in 125%, 150% or even other scaling modes, then the GUI will resize properly, without some components being too small or too big.

Unfortunately, as per the advice of the aforementioned link: "Only the controls in the Controls lists when ResumeLayout at the end of InitializeComponent is called will be auto-scaled", which means I need to put the above two lines in the Designer.cs file. I can't simply put them later in the Form Load event.

Unfortunately, this means that whenever I update or move about a widget/button/label in the Wysiwyg editor, the Designer.cs file is automatically recreated, and I lose my two lines of code above. So I have to keep remembering to put them back in every time I update the GUI in the Wysiwyg editor.

The link also supplies a potential solution to avoid this ugliness by partially avoiding the use of the Wysiwyg editor, and instead creating the splitContainers programmatically in the Load event. I quote: "if you dynamically add controls, then you need to SuspendLayout(); AutoScaleDimensions = new SizeF(6F, 13F); AutoScaleMode = AutoScaleMode.Font; ResumeLayout(); on that control before you add it in".

The problem there is that I have a ton of splitContainer code to move over (such as objects being added to the splitContainers), and it will ruin the look of the Wysiwyg editor (I want to see my splitContainers thank-you-very-much as they are a crucial part of the GUI and have many elements/widgets inside that I also want to see when designing!).

My question is if I can get the best of both worlds: Keep the look of the splitContainers and contents in the Wysiwyg editor, while keeping the functionality of proper scaling by utilizing the two lines of code above (*.AutoScaleMode = ... and *.AutoScaleDimensions = ...) which seemingly must be in the Designer.cs file before *.ResumeLayout() is called.

Dan W
  • 3,520
  • 7
  • 42
  • 69
  • I wonder if @kjbartel can help with this question. – Dan W Oct 05 '21 at 15:55
  • You should probably target at least .Net Framework 4.8 and use `app.config` to specify the DpiAwareness mode you're designing your app for (probably `PerMonitorV2`) -- Automatic scale to Font is quite complicated to get right, have you though about scaling to Dpi instead? If you need to scale the Fonts, you can add an option to your application, so you scale only using your own logic in a pre-configured manner -- BTW, you don't really need to modify the Designer file to Suspend/Resume Layout, you can do the same in the Form's Constructor **after** the call to `InitializeComponent()`. – Jimi Oct 05 '21 at 16:15
  • @Jimi: I want to target as many systems as possible (including Windows 7), hence .NET 4. I have experimented with Dpi, but had problems, and AFAIK, I'd have the same problem there anyway, needing to add the lines of code to the Designer.cs file. You said: "*you don't really need to modify the Designer file to Suspend/Resume Layout*": Unfortunately not, it has to be before the *first* ResumeLayout is called in the Designer.cs file. If I try to Suspend/Resume layout again later, the scaling will be broken, since the scaling logic only takes into account the first time the component is created. – Dan W Oct 05 '21 at 16:22
  • Windows 7 has no problem with .Net Framework 4.8, it just doesn't provide the *recent* enhancement added to Windows 10. Dpi scaling works pretty well anyway. As it does in Windows 10 (still testing Windows 11)-- Again, it's the Form constructor that calls `InitializeComponent()` (the method in the Designer that configures your Layout): hence, you can suspend the Layout again **after** the method call, add any other layout logic, then resume the layout. This includes all Controls that have the `SupportInitialize` feature. -- If your layout is designed correctly, you shouldn't need any of that. – Jimi Oct 05 '21 at 16:28
  • If you don't target at least .Net Framework 4.8, all the Dpi-aware functionality that have been added to the framework only very recently are not available or are only partially working (well, everything is still *partially working* in this department). This implies that you should use the *old way*, aka scale everything manually. If you hope that scaling to Font can be done all automatically or with some magic concoction, you're out of luck. – Jimi Oct 05 '21 at 16:36
  • @Jimi: "*hence, you can suspend the Layout again after the method call, add any other layout logic, then resume the layout*" - As said before, the temperamental scaling logic unfortunately only applies to the first time the object is Suspended/Resumed. If you try to Suspend/Resume again and add those two lines, the scaling won't work properly for users in other scaling modes. I might consider .Net 4.8 later thanks. However, I am using and love VS2010 (MS made future versions slower and more ugly), and I'm not sure what percentage of Windows 7 users have .NET 4.8 installed. – Dan W Oct 05 '21 at 16:40
  • You don't need to add anything to the Designer.cs file, I don't know why you think you have to. Also, yes, of course you can suspend the layout and resume it again whenever needed, to make the LayouEngine apply the layout logic specified. This is very common, hence used very often, so quite *tested*. – Jimi Oct 05 '21 at 16:48
  • @Jimi: I did actually try putting those lines after `InitializeComponent()`, and it didn't work, but don't take my word for it; The original answer I linked from my post also said: "*Only the controls in the Controls lists when ResumeLayout at the end of InitializeComponent is called will be auto-scaled...*". Winforms only seems to apply the scaling logic the first time round. – Dan W Oct 05 '21 at 17:03
  • ...and what does it say immediately after the cut out part you quoted? Exactly what I just said, which is quite obvious since it's the standard behavior. I don't know what you did and I'm not really not sure what you're trying accomplish. -- Anyway, a Form or any container Control can be re-scaled at any time, as it usually happens when you move a Window of a Dpi-Aware application from a screen to another with a different Dpi and/or System or User-defined scale. – Jimi Oct 05 '21 at 17:38
  • @Jimi: On the chance you were right, I checked again: After `InitializeComponent()`, I put `Form1.SuspendLayout()` and the `splitContainerX.SuspendLayout();` lines with the `splitContainerX.AutoScaleMode = ...` and `splitContainerX.AutoScaleDimensions = ...` lines, with ResumeLayout() for the Form/splitContainers. Switched to 125% and had the scaling problem. As a reality check, I then moved these lines (minus the Suspend/Resume ones obviously) to the Designer.cs, and it works again. "*cut out part you quoted*": That's for dynamically added controls which are not in the Designer to begin with. – Dan W Oct 05 '21 at 18:29
  • 1
    Derive your own class from SplitContainer, with a constructor that sets the properties you want. Replace the existing splitter with the derived one. – Hans Passant Oct 05 '21 at 21:33
  • @HansPassant: That sounds great. Why don't you make that an official answer below? – Dan W Oct 05 '21 at 22:44
  • @HansPassant: Finally got round to trying this out in the latest release (rearranging the GUI was a bit of a nightmare), annnnnd............. it works, kind of! There's just one issue where the buttons (and labels I think) inside the (extended) `SplitContainer` are smaller, despite the buttons elsewhere on the form looking good! Somehow, correcting the SplitContainer has made its child elements go wonky. Not sure how to solve this as I can't even set `AutoScaleMode` for a button. Here's a before/after screenshot to demonstrate: https://i.imgur.com/QpZyBBa.png – Dan W Oct 29 '22 at 10:32

0 Answers0