-1

I have code to resize controls on my forms, so that they can display "responsively" on any screen resolution, this code is working perfectly on some of my forms but unfortunately is not working on my other forms.

I was suspecting that maybe because some of the controls where in Group-boxes and panels, so maybe they where not being "reached", but the code has proved that is is not the answer.

Here is some of the code

#region Scale Controls To Screen Size

        Responsive ResponsiveObj;

        private void ScaleControls(Control.ControlCollection controls)
        {
            foreach (Control ctl in controls)
            {
                Scale(ctl);
                if (ctl is GroupBox || ctl is StatusStrip || ctl is DevExpress.XtraEditors.BarCodeControl || ctl is Panel || ctl is LabelControl || ctl is DevExpress.XtraBars.Navigation.TabPane || ctl is DevExpress.XtraBars.Navigation.TabNavigationPage)   // Recursive call if it is a Groupbox (which has more controls inside it).
                    ScaleControls(ctl.Controls);
            }
        }

        private void Scale(Control ctl)
        {
            ctl.Font = new Font(ctl.Font.Name, ResponsiveObj.GetMetrics((int)ctl.Font.Size), ctl.Font.Style);
            if (ctl is LookUpEdit)
            {
                (ctl as LookUpEdit).Properties.Appearance.Font = ctl.Font;
                (ctl as LookUpEdit).Properties.AppearanceDisabled.Font = ctl.Font;
                (ctl as LookUpEdit).Properties.AppearanceDropDown.Font = ctl.Font;
                (ctl as LookUpEdit).Properties.AppearanceDropDownHeader.Font = ctl.Font;
                (ctl as LookUpEdit).Properties.AppearanceFocused.Font = ctl.Font;
                (ctl as LookUpEdit).Properties.AppearanceReadOnly.Font = ctl.Font;
            }
            ctl.Width = ResponsiveObj.GetMetrics(ctl.Width, "Width");
            ctl.Height = ResponsiveObj.GetMetrics(ctl.Height, "Height");
            ctl.Top = ResponsiveObj.GetMetrics(ctl.Top, "Top");
            ctl.Left = ResponsiveObj.GetMetrics(ctl.Left, "Left");
        }

        #endregion

In the constructor

ResponsiveObj = new Responsive(Screen.PrimaryScreen.Bounds);
ResponsiveObj.SetMultiplicationFactor();

In the Form Load event

Width = ResponsiveObj.GetMetrics(Width, "Width");    // Form width and height set up.
Height = ResponsiveObj.GetMetrics(Height, "Height");
Left = Screen.GetBounds(this).Width / 2 - Width / 2;  // Form centering.
Top = Screen.GetBounds(this).Height / 2 - Height / 2 - 30;  // 30 is a calibration factor.

ScaleControls(Controls);

I thought maybe the ScaleControls procedure was not accessing all the controls so I changed it but still got the same result

private void ScaleControls(Control.ControlCollection controls)
{
            foreach (Control ctl in controls)
            {
                Scale(ctl);
                if (ctl.HasChildren)   // Recursive call if it is a Groupbox (which has more controls inside it).
                    ScaleControls(ctl.Controls);
            }
}

The Image shows a resized TextEdit at the bottom and on top of it are two similar TextEdit controls that were not resized

I am realizing that some of my controls might not be included in the controls collection like the TextEdit control for example - I am trying to find a way to create a list of all controls including the TextEdit control along with other DevExpress controls so that they can be resized

I just uploaded a sample project on Microsoft Onedrive here. The project was developed on a 1920 * 1080 monitor but we want the forms to adjust and show nicely even on other smaller monitors like 1600 * 900 for example. The first form In Big responds well on other smaller monitor the font sizes are scaled properly and the controls are placed rightly on 1600 * 900 monitors. But the second form Outbound is not resized right . the Full Weight and Empty Weight TextEdit are not resized and the font is not right - and yet that form is a copy of the In Big form with a few adjustments.I would like for the controls and fonts to resize properly even in the Outbound form like its doing in the In Big form

I found out that in the "Big In" form the tabPane DevExpress control was docked but in the other forms it was not . this suttle difference was the one causing the problem

Tendai Mare
  • 31
  • 1
  • 2
  • 14
  • See following : https://learn.microsoft.com/en-us/dotnet/framework/winforms/automatic-scaling-in-windows-forms – jdweng Oct 30 '19 at 12:47
  • 1
    If I understand correctly the problem with #1 is that it should fit in the box and not show the dots? If so I think you might want to look at Graphics.MeasureString (take a look at this post https://stackoverflow.com/questions/15571715/auto-resize-font-to-fit-rectangle) – Kevin Oct 30 '19 at 13:17
  • Exactly on my other forms the controls and fonts resize perfectly. but then for some reason on other forms it doesn't resize as it should. – Tendai Mare Oct 30 '19 at 13:22
  • Is your application DPIAware? Note that some DevExpress controls reference WPF assemblies. This can change the appearence of some of the Windows, if the application is not DPIAware. – Jimi Oct 30 '19 at 13:28
  • I'll have to look into this but whats bugging me is that some DevExpress forms that have lots of controls on them are resizing perfectly and the some other forms that are almost similar are not resizing as they should – Tendai Mare Oct 30 '19 at 13:32
  • The notes here may be useful: [DPI Awareness - Unaware in one Release, System Aware in the Other](https://stackoverflow.com/a/50276714/7444103). See also the duplicate – Jimi Oct 30 '19 at 17:15
  • Just as a side note, if you try to use the Controls property of a StatusStrip, then it will not work. The StatusStrip for example uses the Items property instead. The documentation says for the controls property: "This property is not relevant for this class." see: [https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.statusstrip?view=netframework-4.8](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.statusstrip?view=netframework-4.8) – Thomas Voß Nov 02 '19 at 09:00
  • 1
    @TendaiMare: Try setting ctl.BackColor = Color.Red; in the ScaleControls to make sure it covers all the controls. – CharithJ Nov 07 '19 at 04:57

1 Answers1

1

Starting with the .NET Framework 4.7, Windows Forms includes enhancements for common high DPI and dynamic DPI scenarios. These include:

Improvements in the scaling and layout of a number of Windows Forms controls, such as the MonthCalendar control and the CheckedListBox control.

Single-pass scaling. In the .NET Framework 4.6 and earlier versions, scaling was performed through multiple passes, which caused some controls to be scaled more than was necessary.

Support for dynamic DPI scenarios in which the user changes the DPI or scale factor after a Windows Forms application has been launched.

In versions of the .NET Framework starting with the .NET Framework 4.7, enhanced high DPI support is an opt-in feature. You must configure your application to take advantage of it.

Configuring your Windows Forms app for high DPI support

The new Windows Forms features that support high DPI awareness are available only in applications that target the .NET Framework 4.7 and are running on Windows operating systems starting with the Windows 10 Creators Update.

In addition, to configure high DPI support in your Windows Forms application, you must do the following:

Declare compatibility with Windows 10.

To do this, add the following to your manifest file:

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
  <application>
    <!-- Windows 10 compatibility -->
    <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
  </application>
</compatibility>

Enable per-monitor DPI awareness in the app.config file.

Windows Forms introduces a new element to support new features and customizations added starting with the .NET Framework 4.7. To take advantage of the new features that support high DPI, add the following to your application configuration file.

<System.Windows.Forms.ApplicationConfigurationSection>
  <add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>

Call the static EnableVisualStyles method.

This should be the first method call in your application entry point. For example:

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form2());
}

Opting out of individual high DPI features Setting the DpiAwareness value to PerMonitorV2 enables all high DPI awareness features supported by .NET Framework versions starting with the .NET Framework 4.7. Typically, this is adequate for most Windows Forms applications. However, you may want to opt out of one or more individual features. The most important reason for doing this is that your existing application code already handles that feature. For example, if your application handles auto scaling, you might want to disable the auto-resizing feature as follows:

<System.Windows.Forms.ApplicationConfigurationSection>
  <add key="DpiAwareness" value="PerMonitorV2" />
  <add key="EnableWindowsFormsHighDpiAutoResizing" value="false" />
</System.Windows.Forms.ApplicationConfigurationSection>

For more Configuration related Help :: Read :: https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/winforms/windows-forms-add-configuration-element

Hope this will make your application look good !!

N.K
  • 2,220
  • 1
  • 14
  • 44