Alle ContainerControls müssen gleich eingestellt sein AutoScaleMode = Font
. (Die Schriftart behandelt sowohl DPI-Änderungen als auch Änderungen an der Einstellung der Systemschriftgröße. DPI behandelt nur DPI-Änderungen, keine Änderungen an der Einstellung der Systemschriftgröße.)
Alle ContainerControls müssen ebenfalls mit derselben AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
Einstellung eingestellt werden , vorausgesetzt 96 dpi (siehe nächster Punkt) und die Standardschriftart von MS Sans Serif (siehe Punkt 2 unten). Dies wird vom Designer basierend auf der DPI, in der Sie den Designer öffnen, automatisch hinzugefügt, fehlte jedoch in vielen unserer ältesten Designer-Dateien. Möglicherweise hat Visual Studio .NET (die Version vor VS 2005) dies nicht richtig hinzugefügt.
Arbeiten Sie alle Ihre Designer mit 96 dpi (wir können möglicherweise auf 120 dpi umschalten; aber die Weisheit im Internet besagt, dass Sie sich an 96 dpi halten müssen; Experimente sind dort angebracht; von Natur aus sollte es keine Rolle spielen, da es nur die AutoScaleDimensions
Linie ändert, die die Designereinsätze). Um festzulegen, dass Visual Studio auf einer hochauflösenden Anzeige mit einer virtuellen Auflösung von 96 dpi ausgeführt wird, suchen Sie die EXE-Datei, klicken Sie mit der rechten Maustaste, um die Eigenschaften zu bearbeiten, und wählen Sie unter Kompatibilität die Option "Skalierungsverhalten mit hoher DPI überschreiben. Skalierung durchgeführt von: System".
Stellen Sie sicher, dass Sie die Schriftart niemals auf Containerebene festlegen ... nur auf den Blattsteuerelementen ODER im Konstruktor Ihres Basisformulars, wenn Sie eine andere anwendungsweite Standardschrift als MS Sans Serif möchten. (Das Festlegen der Schriftart für einen Container scheint die automatische Skalierung dieses Containers zu deaktivieren, da sie alphabetisch nach dem Festlegen der Einstellungen für AutoScaleMode und AutoScaleDimensions erfolgt.) HINWEIS: Wenn Sie die Schriftart im Konstruktor Ihres Basisformulars ändern, führt dies dazu Ihre AutoScaleDimensions müssen anders als 6x13 berechnet werden. Insbesondere wenn Sie zur Segoe-Benutzeroberfläche (der Win 10-Standardschriftart) wechseln, ist diese 7 x 15 ... Sie müssen jedes Formular im Designer berühren, damit alle Dimensionen in dieser Designer-Datei neu berechnet werden können, einschließlich die AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
.
Verwenden Sie NICHT Anker Right
oder Bottom
verankert in einem UserControl ... seine Positionierung wird nicht automatisch skaliert. Legen Sie stattdessen ein Bedienfeld oder einen anderen Container in Ihrem UserControl ab und verankern Sie Ihre anderen Steuerelemente in diesem Bedienfeld. hat die Panel Verwendung Dock Right
, Bottom
oder Fill
in Ihrem Usercontrol.
Nur die Steuerelemente in den Steuerelementlisten, die ResumeLayout
am Ende von InitializeComponent
aufgerufen werden, werden automatisch skaliert. Wenn Sie Steuerelemente dynamisch hinzufügen, müssen Sie SuspendLayout();
AutoScaleDimensions = new SizeF(6F, 13F);
AutoScaleMode = AutoScaleMode.Font;
ResumeLayout();
dieses Steuerelement aktivieren, bevor Sie es hinzufügen. Außerdem muss Ihre Positionierung angepasst werden Wenn Sie keine Dock-Modi oder einen Layout-Manager wie FlowLayoutPanel
oder verwenden TableLayoutPanel
.
Von abgeleitete Basisklassen ContainerControl
sollten auf AutoScaleMode
gesetzt bleiben Inherit
(der in der Klasse festgelegte Standardwert ContainerControl
; aber NICHT der vom Designer festgelegte Standardwert). Wenn Sie es auf etwas anderes setzen und Ihre abgeleitete Klasse dann versucht, es auf Font zu setzen (wie es sollte), wird durch das Einstellen dieser Font
Einstellung die Einstellung des Designers AutoScaleDimensions
gelöscht, was dazu führt, dass die automatische Skalierung tatsächlich deaktiviert wird! (Diese Richtlinie in Kombination mit der vorherigen bedeutet, dass Sie in einem Designer niemals Basisklassen instanziieren können. Alle Klassen müssen entweder als Basisklassen oder als Blattklassen entworfen werden!)
Vermeiden Sie die Verwendung Form.MaxSize
statisch / im Designer. MinSize
und MaxSize
auf Form skalieren Sie nicht so viel wie alles andere. Wenn Sie also Ihre gesamte Arbeit mit 96 dpi erledigen, verursachen Sie bei höheren DPI-Werten MinSize
keine Probleme, sind jedoch möglicherweise nicht so restriktiv wie erwartet, aber Sie MaxSize
können die Skalierung Ihrer Größe einschränken, was zu Problemen führen kann. Wenn Sie möchten MinSize == Size == MaxSize
, tun Sie dies nicht im Designer ... tun Sie dies in Ihrem Konstruktor oder OnLoad
überschreiben Sie ... stellen Sie beide MinSize
und MaxSize
Ihre richtig skalierte Größe ein.
Alle Steuerelemente eines bestimmten Panel
oder Container
sollten entweder Verankerung oder Andocken verwenden. Wenn Sie sie mischen, verhält sich die dadurch vorgenommene automatische Skalierung Panel
oft auf subtile bizarre Weise schlecht.
Wenn es seine automatische Skalierung durchführt, wird es versuchen, das gesamte Formular zu skalieren. Wenn es dabei jedoch an die Obergrenze der Bildschirmgröße stößt, ist dies eine harte Grenze, die es dann vermasseln kann (Clip). die Skalierung. Stellen Sie daher sicher, dass alle Formulare im Designer mit 100% / 96 dpi nicht größer als 1024 x 720 sind (dies entspricht 150% auf einem 1080p-Bildschirm oder 300%, was dem von Windows empfohlenen Wert auf einem 4K-Bildschirm entspricht). Aber Sie müssen für die riesige Win10-Titel- / Beschriftungsleiste subtrahieren ... also eher 1000x680 max Size ... was im Designer 994x642 ClientSize entspricht. (Sie können also auf ClientSize FindAll-Referenzen erstellen, um Verstöße zu finden.)
NumericUpDown
skaliert es auch nichtMargin
richtig. Es scheint, dass der Rand zweimal skaliert ist. Wenn ich es einmal verkleinere, sieht es gut aus.AutoScaleMode = Font
funktioniert nicht gut für Benutzer, die eine sehr große Schriftart verwenden und mit unter Ubuntu. Wir bevorzugenAutoScaleMode = DPI
Meine Erfahrung war ziemlich anders als die aktuelle Antwort mit der höchsten Abstimmung. Durch Durchlaufen des .NET Framework-Codes und Durchsuchen des Referenzquellcodes kam ich zu dem Schluss, dass alles vorhanden ist, damit die automatische Skalierung funktioniert, und dass irgendwo nur ein subtiles Problem aufgetreten ist. Dies stellte sich als wahr heraus.
Wenn Sie ein ordnungsgemäß reflowfähiges Layout mit automatischer Größe erstellen, funktioniert fast alles genau so, wie es automatisch mit den von Visual Studio verwendeten Standardeinstellungen funktionieren sollte (nämlich AutoSizeMode = Schriftart im übergeordneten Formular und Inherit für alles andere).
Das einzige Problem ist, wenn Sie die Font-Eigenschaft für das Formular im Designer festgelegt haben. Der generierte Code sortiert die Zuordnungen alphabetisch, dh die Zuweisungen
AutoScaleDimensions
werden zuvor zugewiesenFont
. Leider bricht dies die automatische Skalierungslogik von WinForms vollständig.Das Update ist jedoch einfach. Legen Sie die
Font
Eigenschaft entweder überhaupt nicht im Designer fest (legen Sie sie in Ihrem Formularkonstruktor fest) oder ordnen Sie diese Zuweisungen manuell neu an (aber Sie müssen dies jedes Mal tun, wenn Sie das Formular im Designer bearbeiten). Voila, nahezu perfekte und vollautomatische Skalierung mit minimalem Aufwand. Auch die Formulargrößen sind korrekt skaliert.Ich werde hier bekannte Probleme auflisten, wenn ich auf sie stoße:
TableLayoutPanel
berechnet die Kontrollränder falsch . Keine bekannte Problemumgehung, außer Ränder und Auffüllungen insgesamt zu vermeiden - oder verschachtelte Tabellenlayoutfelder zu vermeiden.quelle
Font
im Designer: Ein Gedanke kommt in den Sinn: Stellen Sie die Schriftart im Designer ein, damit Sie mit der gewünschten Schriftart entwerfen können. DANN im Konstruktor nach dem Layout diese Schrifteigenschaft lesen und denselben Wert wieder zurücksetzen? Oder fragen Sie einfach nach dem Layout, das noch einmal gemacht werden soll? [Vorsichtsmaßnahme: Ich hatte keinen Grund, diesen Ansatz zu testen.] Oder gemäß der Antwort von Knowleech im Designer in Pixel angeben (damit der Visual Studio-Designer auf einem Monitor mit hoher DPI nicht neu skaliert) und im Code diesen Wert lesen, aus Pixeln konvertieren zu Punkten (um die richtige Skalierung zu erhalten).AutoScaleDimensions
nicht dienew SizeF(6F, 13F)
in der oberen Antwort empfohlenen Werte festgelegt wurden. Es stellte sich heraus, dass in jedem Fall die Font-Eigenschaft des Formulars festgelegt wurde (nicht die Standardeinstellung). Es scheint, dass wennAutoScaleMode = Font
, dannAutoScaleDimensions
basierend auf der Schrifteigenschaft des Formulars berechnet wird. Auch die Skalierungseinstellung in der Windows-Systemsteuerung scheint Auswirkungen zu habenAutoScaleDimensions
.Richten Sie Ihre Anwendung auf .Net Framework 4.7 aus und führen Sie sie unter Windows 10 v1703 aus (Creators Update Build 15063). Mit .Net 4.7 unter Windows 10 (v1703) hat MS viele DPI-Verbesserungen vorgenommen .
Fügen Sie Ihrer Anwendung ein Anwendungsmanifest hinzu und signalisieren Sie, dass Ihre App Windows 10 unterstützt:
Fügen Sie als Nächstes eine hinzu
app.config
und deklarieren Sie die App Per Monitor Aware. Dies geschieht JETZT in app.config und NICHT wie zuvor im Manifest!Dieser PerMonitorV2 ist seit dem Windows 10 Creators Update neu:
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
Jetzt können Sie 3 neue Ereignisse abonnieren, um über DPI-Änderungen informiert zu werden:
Sie haben auch 3 Hilfsmethoden zur Behandlung / Skalierung von DPI:
Control.LogicalToDeviceUnits , das einen Wert von logischen in Gerätepixel konvertiert.
Control.ScaleBitmapLogicalToDevice , das ein Bitmap-Image auf die logische DPI eines Geräts skaliert.
Control.DeviceDpi , das die DPI für das aktuelle Gerät zurückgibt.
Wenn weiterhin Probleme auftreten, können Sie die DPI-Verbesserungen über app.config-Einträge deaktivieren .
Wenn Sie keinen Zugriff auf den Quellcode haben, können Sie die Anwendungseigenschaften im Windows Explorer aufrufen, zur Kompatibilität wechseln und auswählen
System (Enhanced)
Hiermit wird die GDI-Skalierung aktiviert, um auch die DPI-Verarbeitung zu verbessern:
Wenn Sie all diese Schritte ausführen, sollten Sie eine bessere DPI-Erfahrung für WinForms-Anwendungen erhalten. Denken Sie jedoch daran, dass Sie Ihre App auf .net 4.7 ausrichten müssen und mindestens Windows 10 Build 15063 (Creators Update) benötigen. Im nächsten Windows 10 Update 1709 werden wir möglicherweise weitere Verbesserungen erhalten.
quelle
Ein Leitfaden, den ich bei der Arbeit geschrieben habe:
quelle
Ich fand es sehr schwierig, WinForms dazu zu bringen, mit hoher DPI gut zu spielen. Also habe ich eine VB.NET-Methode geschrieben, um das Formularverhalten zu überschreiben:
quelle
Ich bin kürzlich auf dieses Problem gestoßen, insbesondere in Kombination mit der Neuskalierung von Visual Studio, wenn der Editor auf einem System mit hoher Auflösung geöffnet wird. Ich fand es am besten zu halten
AutoScaleMode = Font
, aber die Formen setzen Schriftart auf die Standardschrift, aber die Größe in Pixel spezifiziert , nicht Punkt, das heißt:Font = MS Sans; 11px
. Im Code habe ich dann die Schriftart auf die Standardeinstellung zurückgesetzt:Font = SystemFonts.DefaultFont
und alles ist in Ordnung.Nur meine zwei Cent. Ich dachte, ich teile, weil "AutoScaleMode = Schriftart beibehalten" und "Schriftgröße in Pixel für den Designer festlegen " etwas war, das ich im Internet nicht gefunden habe.
Ich habe einige weitere Details in meinem Blog: http://www.sgrottel.de/?p=1581&lang=de
quelle
Zusätzlich zu den Ankern, die nicht sehr gut funktionieren: Ich würde einen Schritt weiter gehen und sagen, dass die genaue Positionierung (auch bekannt als Verwendung der Location-Eigenschaft) mit der Schriftartenskalierung nicht sehr gut funktioniert. Ich musste dieses Problem in zwei verschiedenen Projekten ansprechen. In beiden Fällen mussten wir die Positionierung aller WinForms-Steuerelemente in die Verwendung von TableLayoutPanel und FlowLayoutPanel konvertieren. Die Verwendung der Dock-Eigenschaft (normalerweise auf Fill gesetzt) im TableLayoutPanel funktioniert sehr gut und lässt sich gut mit der DPI-Systemschriftart skalieren.
quelle