Todos los ContainerControls deben configurarse igual AutoScaleMode = Font
. (La fuente manejará los cambios de DPI y los cambios en la configuración del tamaño de fuente del sistema; DPI solo manejará los cambios de DPI, no los cambios en la configuración del tamaño de fuente del sistema).
Todos los ContainerControls también se deben configurar con el mismo AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
, suponiendo 96 ppp (consulte la siguiente viñeta) y la Fuente predeterminada de MS Sans Serif (consulte la viñeta dos abajo). El diseñador lo agrega automáticamente en función del DPI en el que abre el diseñador ... pero faltaba en muchos de nuestros archivos de diseñador más antiguos. Quizás Visual Studio .NET (la versión anterior a VS 2005) no estaba agregando eso correctamente.
Realice todo su trabajo de diseñador en 96 ppp (es posible que podamos cambiar a 120 ppp; pero la sabiduría en Internet dice que se mantenga en 96 ppp; la experimentación está en orden allí; por diseño, no debería importar ya que solo cambia la AutoScaleDimensions
línea que el diseñador inserta). Para configurar Visual Studio para que se ejecute a 96 ppp virtuales en una pantalla de alta resolución, busque su archivo .exe, haga clic con el botón derecho para editar propiedades y, en Compatibilidad, seleccione "Anular el comportamiento de escalado de DPI alto. Escalado realizado por: Sistema".
Asegúrese de nunca configurar la Fuente en el nivel del contenedor ... solo en los controles de hoja O en el constructor de su Formulario más básico si desea una Fuente predeterminada para toda la aplicación que no sea MS Sans Serif. (Establecer la Fuente en un Contenedor parece desactivar la escala automática de ese contenedor porque viene alfabéticamente después de la configuración de las configuraciones AutoScaleMode y AutoScaleDimensions). TENGA EN CUENTA que si cambia la Fuente en el constructor de su Forma más básica, eso causará sus AutoScaleDimensions para calcular de manera diferente a 6x13; en particular, si cambia a la interfaz de usuario de Segoe (la fuente predeterminada de Win 10), entonces será 7x15 ... deberá tocar todos los formularios del Diseñador para que pueda volver a calcular todas las dimensiones en ese archivo .designer, incluido el AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
.
NO use Anclar Right
o Bottom
anclado a un UserControl ... su posicionamiento no se escalará automáticamente; en su lugar, suelte un Panel u otro contenedor en su Control de usuario y ancle sus otros Controles en ese Panel; tiene el uso del panel del muelle Right
, Bottom
o Fill
en su control de usuario.
Solo los controles en las listas de Controles cuando se llama ResumeLayout
al final de InitializeComponent
se escalarán automáticamente ... si agrega controles dinámicamente, entonces debe SuspendLayout();
AutoScaleDimensions = new SizeF(6F, 13F);
AutoScaleMode = AutoScaleMode.Font;
ResumeLayout();
activar ese control antes de agregarlo. Y su posición también necesitará ser ajustada si no está utilizando los modos Dock o un Layout Manager como FlowLayoutPanel
o TableLayoutPanel
.
Las clases base derivadas de ContainerControl
deberían dejarse AutoScaleMode
establecidas en Inherit
(el valor predeterminado establecido en la clase ContainerControl
; pero NO el predeterminado establecido por el diseñador). Si lo configura en cualquier otra cosa, y su clase derivada intenta establecerlo en Fuente (como debería), entonces el acto de establecer eso Font
borrará la configuración del diseñador AutoScaleDimensions
, ¡lo que en realidad desactivará la escala automática! (Esta guía combinada con la anterior significa que nunca puede crear instancias de clases base en un diseñador ... ¡todas las clases deben diseñarse como clases base o como clases hoja!)
Evite usar Form.MaxSize
estáticamente / en el Diseñador. MinSize
y MaxSize
en Form no escalan tanto como todo lo demás. Por lo tanto, si hace todo su trabajo en 96 ppp, cuando tenga un DPI más alto MinSize
, no causará problemas, pero puede que no sea tan restrictivo como esperaba, pero MaxSize
puede limitar la escala de su Tamaño, lo que puede causar problemas. Si lo desea MinSize == Size == MaxSize
, no lo haga en el Diseñador ... hágalo en su constructor o OnLoad
anule ... establezca ambos MinSize
y MaxSize
su Tamaño debidamente escalado.
Todos los controles en un particular Panel
o Container
deben usar anclaje o acoplamiento. Si los mezcla, el autoescalado realizado Panel
a menudo se comportará mal de maneras sutiles y extrañas.
Cuando haga su autoescalado, intentará escalar el formulario general ... sin embargo, si en ese proceso se encuentra con el límite superior del tamaño de la pantalla, ese es un límite difícil que luego puede arruinarse (clip) La escala. Por lo tanto, debe asegurarse de que todos los formularios en el diseñador al 100% / 96 ppp tengan un tamaño no mayor a 1024x720 (que corresponde al 150% en una pantalla de 1080p o 300%, que es el valor recomendado de Windows en una pantalla 4K). Pero debes restar la barra de título / título Win10 gigante ... así que más como 1000x680 max Size ... que en el diseñador será como 994x642 ClientSize. (Por lo tanto, puede hacer un FindAll References en ClientSize para encontrar infractores)
NumericUpDown
no escalaMargin
adecuadamente, también. Parece que el margen se escala dos veces. Si lo escalo una vez, se ve bien.AutoScaleMode = Font
no funciona bien para usuarios que usan una fuente muy grande y con Ubuntu. PreferimosAutoScaleMode = DPI
Mi experiencia ha sido bastante diferente a la respuesta actual más votada. Al recorrer el código del framework .NET y leer detenidamente el código fuente de referencia, llegué a la conclusión de que todo está en su lugar para que funcione el autoescalado, y solo hubo un problema sutil en algún lugar que lo estropeó. Esto resultó ser cierto.
Si crea un diseño correctamente reembolsable / de tamaño automático, casi todo funciona exactamente como debería, automáticamente, con la configuración predeterminada utilizada por Visual Studio (a saber, AutoSizeMode = Font en el formulario principal e Heredar en todo lo demás).
El único problema es si ha configurado la propiedad Font en el formulario del diseñador. El código generado ordenará las asignaciones alfabéticamente, lo que significa que
AutoScaleDimensions
se asignarán antesFont
. Desafortunadamente, esto rompe completamente la lógica de escalado automático de WinForms.Sin embargo, la solución es simple. No establezca la
Font
propiedad en el diseñador en absoluto (configúrela en su constructor de formularios), o reordene manualmente estas asignaciones (pero luego debe seguir haciendo esto cada vez que edite el formulario en el diseñador). Voila, escalamiento casi perfecto y totalmente automático con una molestia mínima. Incluso los tamaños de los formularios se escalan correctamente.Enumeraré los problemas conocidos aquí cuando los encuentre:
TableLayoutPanel
calcula los márgenes de control incorrectamente . No existe una solución alternativa que evite los márgenes y rellenos por completo, o evite los paneles de diseño de tabla anidados.fuente
Font
en el diseñador: se me ocurre una idea: siga adelante y configure la fuente en el diseñador, de modo que pueda diseñar con la fuente deseada. ¿ENTONCES en el constructor, después del diseño, lea esa propiedad de fuente y vuelva a establecer el mismo valor? ¿O tal vez solo pedir que se vuelva a hacer el diseño? [Advertencia: no he tenido motivos para probar este enfoque.] O según la respuesta de Knowleech , en el diseñador, especifique en píxeles (para que el diseñador de Visual Studio no cambie la escala en un monitor de DPI alto), y en el código lea ese valor, convierta de píxeles a puntos (para obtener la escala correcta).AutoScaleDimensions
no estaba configuradonew SizeF(6F, 13F)
como se recomienda en la respuesta superior. Resultó que en cada caso, la propiedad Fuente del formulario se había establecido (no predeterminada). Parece que cuandoAutoScaleMode = Font
, entoncesAutoScaleDimensions
se calcula en función de la propiedad de fuente del formulario. Además, la configuración de Escalado en el Panel de control de Windows parece tener un efectoAutoScaleDimensions
.Dirija su aplicación para .Net Framework 4.7 y ejecútela en Windows 10 v1703 (Creators Update Build 15063). Con .Net 4.7 en Windows 10 (v1703), MS realizó muchas mejoras en DPI .
Para admitirlo, agregue un manifiesto de aplicación a su aplicación y señale que su aplicación es compatible con Windows 10:
A continuación, agregue un
app.config
y declare la aplicación Per Monitor Aware. ¡Esto se hace AHORA en app.config y NO en el manifiesto como antes!Este PerMonitorV2 es nuevo desde Windows 10 Creators Update:
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
Ahora puede suscribirse a 3 nuevos eventos para recibir notificaciones sobre los cambios de DPI:
También tiene 3 métodos auxiliares sobre el manejo / escalado de DPI:
Control.LogicalToDeviceUnits , que convierte un valor de lógico a píxeles del dispositivo.
Control.ScaleBitmapLogicalToDevice , que escala una imagen de mapa de bits al DPI lógico para un dispositivo.
Control.DeviceDpi , que devuelve el DPI para el dispositivo actual.
Si sigue apareciendo problemas, puede darse de baja de las mejoras DPI a través de las entradas app.config .
Si no tiene acceso al código fuente, puede ir a las propiedades de la aplicación en el Explorador de Windows, ir a compatibilidad y seleccionar
System (Enhanced)
que activa la escala de GDI para mejorar también el manejo de DPI:
Siga todos esos pasos y debería obtener una mejor experiencia DPI para las aplicaciones WinForms. Pero recuerde, debe orientar su aplicación a .net 4.7 y necesita al menos Windows 10 Build 15063 (Actualización de creadores). En la próxima actualización de Windows 10 1709, podríamos obtener más mejoras.
fuente
Una guía que escribí en el trabajo:
fuente
Descubrí que es muy difícil hacer que WinForms juegue bien con un DPI alto. Entonces, escribí un método VB.NET para anular el comportamiento del formulario:
fuente
Recientemente me encontré con este problema, especialmente en combinación con el cambio de escala de Visual Studio cuando el editor se abre en un sistema de alta resolución. He encontrado que la mejor manera de mantener
AutoScaleMode = Font
, sino para establecer las Formas de fuente a la fuente por defecto, pero se especifica el tamaño en píxeles , no punto, es decir:Font = MS Sans; 11px
. En el código, luego restablezco la fuente al valor predeterminado:Font = SystemFonts.DefaultFont
y todo está bien.Solo mis dos centavos. Pensé en compartir, porque "mantener AutoScaleMode = Font" y "Establecer el tamaño de fuente en píxeles para el Diseñador" era algo que no encontré en Internet.
Tengo algunos detalles más en mi blog: http://www.sgrottel.de/?p=1581&lang=en
fuente
Además de que los anclajes no funcionan muy bien: iría un paso más allá y diría que el posicionamiento exacto (también conocido como uso de la propiedad Ubicación) no funciona muy bien con la escala de la fuente. He tenido que abordar este problema en dos proyectos diferentes. En ambos, tuvimos que convertir el posicionamiento de todos los controles de WinForms para usar TableLayoutPanel y FlowLayoutPanel. El uso de la propiedad Dock (generalmente establecida en Relleno) dentro de TableLayoutPanel funciona muy bien y se adapta bien con la fuente DPI del sistema.
fuente