resolucion redimensionar pantalla maximizar formularios formulario escala controles completa autoscalemode automático aplicacion ajuste ajustar adaptar winforms fonts dpi

winforms - redimensionar - formulario pantalla completa c#



Cómo controlar la fuente DPI en la aplicación.NET WinForms (3)

Establezca AutoScaleMode en Heredar en todas partes (es decir, todos sus UserControls) a través de una búsqueda / reemplazo global, luego configure el AutoScaleMode en Dpi en su formulario principal.

También encuentro que los contenedores de disposición funcionan mejor que los anclajes para este tipo de situación.

Creé una aplicación para una pequeña empresa. Algunos de los empleados de la oficina no pueden ver el formulario correctamente. La razón es que tienen su configuración de DPI configurada en más de 96 ppp. ¿Alguien sabe de una forma de controlar esto?

Para todos los que tienen experiencia con las aplicaciones de winforms, ¿cómo controlan el diseño de su formulario para que DPI no afecte el aspecto de la aplicación?


Sé que es algo drástico, pero considere reescribir su aplicación en WPF. Las aplicaciones WPF tienen el mismo aspecto en cada configuración de DPI.


Suponiendo que no intenta respetar la opción de fuente de UI del usuario (SystemFonts.IconTitleFont) y codifica sus formularios para un solo tamaño de fuente (p. Ej., Tahoma 8pt, Microsoft Sans Serif 8.25pt), puede configurar el AutoScaleMode su formulario en ScaleMode.Dpi .

Esto escalará el tamaño del formulario y la mayoría de los controles secundarios mediante el factor CurrentDpiSetting / 96 llamando a Form.Scale() , que a su vez llama al método ScaleControl() protegido recursivamente sobre sí mismo y todos los controles secundarios. ScaleControl aumentará la posición, el tamaño, la fuente, etc. del control según sea necesario para el nuevo factor de escala.

Advertencia: no todos los controles se escalan correctamente. Las columnas de una vista de lista, por ejemplo, no se ampliarán a medida que la fuente se agranda. Para manejar eso, tendrá que realizar escalas adicionales manualmente según sea necesario. Lo hago anulando el método ScaleControl() protegido y escalando las columnas de la vista de lista manualmente:

public class MyForm : Form { protected override void ScaleControl(SizeF factor, BoundsSpecified specified) { base.ScaleControl(factor, specified); Toolkit.ScaleListViewColumns(listView1, factor); } } public class Toolkit { /// <summary> /// Scale the columns of a listview by the Width scale factor specified in factor /// </summary> /// <param name="listview"></param> /// <param name="factor"></param> /// <example>/* /// protected override void ScaleControl(SizeF factor, BoundsSpecified specified) /// { /// base.ScaleControl(factor, specified); /// /// //ListView columns are not automatically scaled with the ListView, so we /// //must do it manually /// Toolkit.ScaleListViewColumns(lvPermissions, factor); /// } ///</example> public static void ScaleListViewColumns(ListView listview, SizeF factor) { foreach (ColumnHeader column in listview.Columns) { column.Width = (int)Math.Round(column.Width * factor.Width); } } }

Esto está muy bien si solo estás usando controles. Pero si alguna vez usa tamaños de píxel codificados, necesitará escalar el ancho y el largo de sus píxeles según el factor de escala actual del formulario. Algunos ejemplos de situaciones que podrían tener tamaños de píxeles codificados:

  • dibujando un rectángulo alto de 25px
  • dibujar una imagen en la ubicación (11,56) en el formulario
  • estirar dibujando un ícono a 48x48
  • dibujo de texto usando Microsoft Sans Serif 8.25pt
  • obtener el formato 32x32 de un icono y rellenarlo en un PictureBox

Si este es el caso, tendrá que escalar esos valores codificados por el " factor de escala actual ". Desafortunadamente, no se proporciona el factor de escala "actual", necesitamos registrarlo nosotros mismos. La solución es suponer que inicialmente el factor de escala es 1.0 y cada vez que se llama ScaleControl() , modifique el factor de escala en ejecución por el nuevo factor.

public class MyForm : Form { private SizeF currentScaleFactor = new SizeF(1f, 1f); protected override void ScaleControl(SizeF factor, BoundsSpecified specified) { base.ScaleControl(factor, specified); //Record the running scale factor used this.currentScaleFactor = new SizeF( this.currentScaleFactor.Width * factor.Width, this.currentScaleFactor.Height * factor.Height); Toolkit.ScaleListViewColumns(listView1, factor); } }

Inicialmente, el factor de escala es 1.0 . Si la forma se escala entonces por 1.25 , el factor de escala se convierte en:

1.00 * 1.25 = 1.25 //scaling current factor by 125%

Si el formulario se escala a 0.95 , se convierte en el nuevo factor de escala

1.25 * 0.95 = 1.1875 //scaling current factor by 95%

La razón por la que se utiliza un SizeF (en lugar de un único valor de coma flotante) es que las cantidades de escalado pueden ser diferentes en las direcciones xey. Si un formulario se establece en ScaleMode.Font , el formulario se escala al nuevo tamaño de fuente. Las fuentes pueden tener diferentes relaciones de aspecto ( por ejemplo, la interfaz de usuario de Segoe es más alta que Tahoma ). Esto significa que debe escalar valores xey de forma independiente.

Por lo tanto, si desea colocar un control en la ubicación (11,56) , deberá cambiar su código de posición de:

Point pt = new Point(11, 56); control1.Location = pt;

a

Point pt = new Point( (int)Math.Round(11.0*this.scaleFactor.Width), (int)Math.Round(56.0*this.scaleFactor.Height)); control1.Location = pt;

Lo mismo se aplica si fuera a elegir un tamaño de fuente:

Font f = new Font("Segoe UI", 8, GraphicsUnit.Point);

tendría que convertirse en:

Font f = new Font("Segoe UI", 8.0*this.scaleFactor.Width, GraphicsUnit.Point);

Y la extracción de un icono de 32x32 a un mapa de bits cambiaría de:

Image i = new Icon(someIcon, new Size(32, 32)).ToBitmap();

a

Image i = new Icon(someIcon, new Size( (int)Math.Round(32.0*this.scaleFactor.Width), (int)Math.Round(32.0*this.scaleFactor.Height))).ToBitmap();

etc.

El soporte de pantallas DPI no estándar es un impuesto que todos los desarrolladores deben pagar . Pero el hecho de que nadie lo quiera es la razón por la cual Microsoft se dio por vencido y agregó a Vista la capacidad de la tarjeta gráfica para extender cualquier aplicación que no diga que maneja adecuadamente los dpi altos .