I need to be able to resize the ratio of a windows forms along with each of its controls/text/etc. So the goal is to allow the user to select the size depending of the resolution of the screen.
How can this be achieved?
Help is appreciated
You can achieve this using methods and properties such as
Control.Scale(SizeF)
ContainerControl.AutoScaleFactor
ContainerControl.AutoScaleMode
and others.
You can do this in several ways. One way would be to scale entire form using Control.Scale(SizeF) method.
this.Scale(new SizeF(2, 2));
This will scale entire form and it's child controls by factor of 2 by width and height. However, font sizes will not be scaled.
Another way would be to set AutoScaleMode to Font and change font size of the form. Form and controls will scale accordingly.
AutoScaleMode = AutoScaleMode.Font;
Font = new Font("Helvetica", 20);
You should read more about this in MSDN article called Automatic Scaling in Windows Forms.
Related
I use this (C# .NET) call to quickly get an image of a control.
Rectangle rectToCapture = myControl.RectangleToScreen(myControl.Bounds);
However, this only works if my Windows display scaling is set to 100%. If I set the display scaling to 125% this rectangle is totally wrong. How can I capture the correct rectangle regardless of scaling?
Per #Jimi I had to make the form DPIAware.
https://social.msdn.microsoft.com/Forums/windows/en-US/4d3979d4-88df-44af-8b66-16b1d4d41d57/issue-with-vs2015-windows-form-dpi-and-screen-resolution?forum=winforms
I've a WinForms custom control with design-time features that shows a popup.
If I change the system font scaling in the Windows settings (Control Panel\All Control Panel Items\Display) then the labels in the popup are cut.
In this video you can see the different behavior with standard font size and with font size changed to 125%.
Here is screenshot of about form when opening from smart tag at design-time:
Here is screenshot of about form when opening at run-time:
How can I fix this issue?
(Source)
I found a workaround by setting the scale factor to the form before showing it.
public void About()
{
float width, height;
using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero))
{
width = graphics.DpiX / 96;
height = graphics.DpiY / 96;
}
About form = new About();
if (width != 1 || height != 1)
form.Scale(new SizeF(width, height));
form.ShowDialog();
}
It seems to work fine.
The issue in the Visual Studio (VS) designer is that Visual Studio is declared as DPI-aware which means it will handle the different DPI settings by it self. But, the About form does not seem to support different DPI as you have set its AutoScaleModel property to Font.
When About form is used in the WindowsFormsApplication1, it works "fine" because the application is declared non-DPI-aware by default. In this case, the operation system will render the form as a bitmap in a sandbox and scales it up before showing it on screen, so you can see texts are fuzzy.
In order to avoid the issue in the VS designer, you have to make sure your About form can handle different DPI settings. Actually your workaround is one of the solution to support different DPI settings.
Update:
This post has detailed description of DPI awareness in WinForms application.
I created a small test application which allows very limited functionality of copying files from one place to another. Now due to the limited functionality, I kept the window size fixed (having maximized as false and well defined height and width of 250x200 pixels). Just 2 file browse elements and a Copy button.
My friends test ran it on their PCs and the problem is that it ran all well for most of my friends, however 3 of them noticed that the height of the application was not enough and the copy button was 80% hidden (only 20% of it was visible). One of them was on a 1920x1080 resolution and the other 2 were on 1366x728. And all the test PCs were Windows 7 computers.
How and why would this possibly happen?
One thing that I can think of one is their DPI setting's are different than your computer.
Control Panel\Appearance and Personalization\Display
having maximized as false and well defined height and width of 250x200 pixels
That's fine, as long as you set this size only in the form constructor. And set the FormBorderStyle to Fixed so it is clear that the window cannot be resized. If you do it later, like in the Load or Resize event then you'll displease users that have a nice high-resolution display. Or a "retina" display, we'll all have them soon. They need to bump up the video adapter's dot-per-inch setting so they can still read 8 point text without a magnifying glass.
Which causes text to get rendered with more pixels. Which requires that your controls get bigger, their sizes are specified in pixels. If you don't let them grow then you'll have small controls with big text, unattractive and unreadable. Bigger controls in turn requires that they move and that your form gets bigger so it still fits the controls.
This is all automatic, thanks to the form's AutoScaleMode setting. It defaults to Font which is just what you need. But that can't work when you force the form back to its original design size, it will clip the moved controls.
A quick way to check if your form still works properly on such a machine, other than tinkering with the video dpi setting, is this bit of test code in the Load event handler:
protected override void OnLoad(EventArgs e) {
this.Font = new Font(this.Font.FontFamily, this.Font.Size * 125 / 96f);
base.OnLoad(e);
}
I've got an app which will run on two different devices - one with a screen size of 240x320, the other 480x640.
For all forms bar one the VS generated code is fine:
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.AutoScroll = true;
For one form i'm capturing a signature. I'm doing this by a panel with a graphics handler; capturing mouse down and move events; this generates a list of vector points which I can draw lines with.
On the smaller res screen this is fine. On the higher res, I can't display my lines.. and I think this is because the panel is beyond the windows form size.
The form is created with a size of 240 x 268; a standard size I think - i've not manually set it, VS does this for me.
In order to get the panel in the right spot on the high res device, the co-ordinates are 3, 290; ie, 290 is past 268. Also the width of the panel is 448 which is somewhat larger than 240.
I'm using .net 2.0 (can't use later). I think I need to resize the form to make it larger but I do want to keep the existing re-sizing for the other controls on the form.
I'm not sure how to do this.
Make the form dock to fill, then use the Anchor properties to ensure controls inside the form resize as expected.
If you want the option of customizing how an individual control resizes, then DONT set the anchor properties on it, and instead handle the Resize event and perform custom resizing/repositioning within code there.
eg
private void form_Resize(object sender, EventArgs e)
{
// Center the control without changing width. Other controls are anchored.
this.control.Left = (this.Width - this.control.Width) / 2;
}
I'm writing this answer for the benefit of those who may have a similar problem in the future. PaulG pointed me in the right direction but I found the root cause to be something else.
The PDA project i've got uses "FormFactor WindowsMobile 6 Classic" which has a default size of 240 x 268.
Changing this to "Windows Mobile 6 Professional VGA" created a much larger form size.
This allowed me to get things positioned correctly for the larger size; then AutoScaleMode to DPI; and manually resizing the panel smaller made it all work.
IE, going from larger to smaller was easy; I didn't get smaller to larger working.
I have a WinForm application which hosts many images. When I put the application on a Win7 machines that has a DPI of 120, it completely ruins the look of the form. Is there a way to disable the scaling for my form?
I am aware that this is something that is not advised and that DPI should be seamless and handled by the OS. But when it comes to a skinned application, the images do not scale well. I do not have the luxury of creating images for all the DPI variations, so please don't suggest that as an answer.
You'll have bigger problems when you change the AutoScaleMode property. Increasing the DPI also changes the system font size. Necessarily so, font sizes are expressed in points, 1/72 inch. The fonts need to be bigger to get the same point size when the DPI increases and keep the text just as readable when viewed from the same distance.
Since the controls don't get resized anymore, the text on, say, a button no longer fits. One way to battle this is to change the font size on the controls proportionally. Easy if you let all the controls inherit the form font, just changing the form's Font property automatically updates the controls as well. The clear disadvantage is that the user will have a harder time reading the text. This especially gets bad when the DPI goes to 150 dots per inch and beyond, your UI just turns into an unusable postage stamp.
Yes, background images need to get scaled to fit the larger control or form. A pixel in the image now no longer maps one-to-one to a pixel of the monitor. The default Graphics.InterpolationMode value does a fairly decent job of filtering the image. But it depends on the kind of image how well that turns out. A photo almost always scales very well. Finely detailed line art and text does not. Picking the right kind of image goes a long way to avoiding having to create separate ones.
This problem isn't going to go away until monitors start to have the kind of resolution a printer has. We're still a long way from 600 dpi for desktop monitors. Phones will be first.
Create a application manifest file (right-click on project/ add/new item/application file) and uncomment this section:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware
</windowsSettings>
</application>
Creds to this site: https://www.telerik.com/blogs/winforms-scaling-at-large-dpi-settings-is-it-even-possible-
Adding one line of code before the auto-generated call to InitializeComponent in the Form1-constructor solved it for me:
public partial class Form1 : Form
{
public Form1()
{
// Make the GUI ignore the DPI setting
Font = new Font(Font.Name, 8.25f * 96f / CreateGraphics().DpiX, Font.Style, Font.Unit, Font.GdiCharSet, Font.GdiVerticalFont);
InitializeComponent();
}
}
You can set the AutoScaleMode property of the form to None.