Automatische Skalierung in Windows Forms

Die automatische Skalierung ermöglicht, dass ein Formular und seine Steuerelemente, die auf einem Computer mit einer bestimmten Bildschirmauflösung oder Systemschriftart entworfen wurden, ordnungsgemäß auf einem anderen Computer angezeigt werden, der eine andere Bildschirmauflösung oder Systemschriftart hat. Durch sie wird sichergestellt, dass die Größen des Formulars und seiner Steuerelemente intelligent geändert werden, sodass diese sowohl auf den Computern von Benutzern als auch auf denen von anderen Entwicklern konsistent zu systemeigenen Fenstern sowie anderen Anwendungen sind. Dadurch, dass .NET Framework die automatische Skalierung und visuelle Stile unterstützt, kann für .NET Framework-Anwendungen im Vergleich zu systemeigenen Windows-Anwendungen ein konsistentes Aussehen und Verhalten auf dem Computer jedes Benutzers beibehalten werden.

In .NET Framework, Version 2.0 oder höher, funktioniert die automatische Skalierung größtenteils wie erwartet. Änderungen des Schriftartenschemas können jedoch problematisch sein. Ein Beispiel für die Lösung finden Sie unter Reagieren auf Änderungen des Schriftartenschemas in einer Windows Forms-Anwendung.

Notwendigkeit der automatischen Skalierung

Ohne automatische Skalierung würde eine Anwendung, die für eine bestimmte Bildschirmauflösung oder Schriftart entworfen wurde, entweder zu klein oder zu groß angezeigt, wenn diese Auflösung oder Schriftart geändert wird. Wurde die Anwendung beispielsweise mit Tahoma 9 Punkt als Basis entworfen, würde sie ohne Anpassung zu klein angezeigt, wenn sie auf einem Computer ausgeführt würde, der die Systemschriftart Tahoma 12 Punkt hat. Textelemente wie Titel, Menüs, Textfeldinhalt usw. werden kleiner gerendert als andere Anwendungen. Darüber hinaus richtet sich die Größe der Benutzeroberflächenelemente, die Text enthalten, etwa die Titelleiste, Menüs und viele Steuerelemente, nach der verwendeten Schriftart. In diesem Beispiel werden diese Elemente zusätzlich relativ kleiner angezeigt.

Die gleiche Situation ergibt sich, wenn eine Anwendung für eine bestimmte Bildschirmauflösung entworfen wurde. Die gängigste Bildschirmauflösung ist 96 DPI (Dots Per Inch), was einer Bildschirmskalierung von 100 Prozent entspricht, aber Bildschirme mit höherer Auflösung, die eine Skalierung von 125, 150, 200 Prozent (entsprechen 120, 144 und 192 DPI) oder darüber unterstützen, werden immer häufiger. Ohne Anpassung wird eine Anwendung, insbesondere eine Grafikanwendung, die für eine bestimme Auflösung entworfen wurde, entweder zu groß oder zu klein angezeigt, wenn sie mit einer anderen Auflösung ausgeführt wird.

Mit der automatischen Skalierung lassen sich diese Probleme abschwächen, indem die Größen des Formulars und seiner untergeordneten Steuerelemente entsprechend der relativen Schriftgröße oder Bildschirmauflösung geändert werden. Windows unterstützt die automatische Skalierung von Dialogfeldern durch Verwenden einer relativen Maßeinheit, die als Dialogeinheiten bezeichnet wird. Eine Dialogeinheit basiert auf der Systemschriftart, und ihre Beziehung zu Pixeln kann über die Win32 SDK-Funktion GetDialogBaseUnits bestimmt werden. Wenn ein Benutzer das von Windows verwendete Design ändert, werden alle Dialogfelder automatisch entsprechend angepasst. Zusätzlich unterstützt .NET Framework die automatische Skalierung entweder entsprechend der Standardsystemschriftart oder der Bildschirmauflösung. Optional kann die automatische Skalierung in einer Anwendung deaktiviert werden.

Ursprüngliche Unterstützung für die automatische Skalierung

In den Versionen 1.0 und 1.1 von .NET Framework wird die automatische Skalierung in einer unkomplizierten Weise unterstützt, die von der Windows-Standardschriftart abhängt, die für die Benutzeroberfläche verwendet und durch den Win32 SDK-Wert DEFAULT_GUI_FONT dargestellt wird. Diese Schriftart wird normalerweise nur geändert, wenn sich die Bildschirmauflösung ändert. Der folgende Mechanismus wurde verwendet, um die automatische Skalierung zu implementieren:

  1. Zur Entwurfszeit wurde die AutoScaleBaseSize-Eigenschaft (die jetzt veraltet ist) auf die Höhe und die Breite der Systemstandardschriftart des Entwicklercomputers festgelegt.

  2. Zur Laufzeit wurde die Systemstandardschriftart des Benutzercomputers verwendet, um die Font-Eigenschaft der Form-Klasse zu initialisieren.

  3. Vor dem Anzeigen des Formulars wurde die ApplyAutoScaling-Methode aufgerufen, um das Formular zu skalieren. Diese Methode hat die relative Skalierungsgröße aus AutoScaleBaseSize und Font berechnet und dann die Scale-Methode aufgerufen, um das Formular und dessen untergeordneten Elemente tatsächlich zu skalieren.

  4. Der Wert von AutoScaleBaseSize wurde aktualisiert, sodass nachfolgende Aufrufe von ApplyAutoScaling die Größe des Formulars nicht zunehmend geändert haben.

Während dieser Mechanismus für die meisten Zwecke ausreichend war, brachte er folgenden Einschränkungen mit sich:

  • Da die AutoScaleBaseSize-Eigenschaft den Basisschriftgrad als ganzzahligen Wert darstellt, treten Rundungsfehler auf, die offensichtlich werden, wenn ein Formular mehrere Auflösungen durchlaufen hat.

  • Automatische Skalierung war nur in der Form-Klasse, nicht in der ContainerControl-Klasse implementiert. Daher wurden Benutzersteuerelemente nur ordnungsgemäß skaliert, wenn das Benutzersteuerelement mit derselben Auflösung wie das Formular entworfen und zur Entwurfszeit im Formular positioniert wurde.

  • Formulare und deren untergeordneten Steuerelemente konnten nur dann gleichzeitig von mehreren Entwicklern gestaltet werden, wenn die Bildschirmauflösungen ihrer Computer identisch waren. Dies bedingte außerdem, dass das Erben durch ein Formular von der Auflösung abhängig war, die dem übergeordneten Formular zugeordnet war.

  • Diese Skalierung ist nicht mit neueren Layout-Managern kompatibel, die mit .NET Framework 2.0 eingeführt wurden, z. B. FlowLayoutPanel und TableLayoutPanel.

  • Der Mechanismus unterstützte keine Skalierung, die direkt auf der Bildschirmauflösung basiert, aber für Kompatibilität mit .NET Compact Framework erforderlich ist.

Obwohl dieser Mechanismus in .NET Framework 2.0 aus Gründen der Abwärtskompatibilität weiterhin unterstützt wird, wurde er durch den robusteren Skalierungsmechanismus ersetzt, der nachstehend beschrieben ist. Als Folge davon sind AutoScale, ApplyAutoScaling, AutoScaleBaseSize und bestimmte Scale-Überladungen als veraltet gekennzeichnet.

Hinweis

Sie können Verweise auf diese Member problemlos löschen, wenn Sie Ihren Legacycode auf .NET Framework 2.0 aktualisieren.

Aktuelle Unterstützung für die automatische Skalierung

.NET Framework 2.0 umgeht frühere Beschränkungen, indem für die automatische Skalierung von Windows Forms die folgenden Änderungen eingeführt wurden:

  • Die Grundunterstützung für Skalierung wurde in die ContainerControl-Klasse verschoben, sodass Formulare, systemeigene zusammengesetzte Steuerelemente und Benutzersteuerelemente eine einheitliche Skalierungsunterstützung haben. Die neuen Member AutoScaleFactor, AutoScaleDimensions, AutoScaleMode und PerformAutoScale wurden hinzugefügt.

  • Die Control-Klasse hat außerdem mehrere neue Member, die ihre Mitwirkung an der Skalierung und die Unterstützung der gemischten Skalierung im selben Formular ermöglichen. Insbesondere die Member Scale, ScaleChildren und GetScaledBounds unterstützen die Skalierung.

  • Unterstützung für Skalierung auf Basis der Bildschirmauflösung wurde hinzugefügt, um die Unterstützung der Systemschriftarten zu ergänzen, wie dies durch die AutoScaleMode-Enumeration definiert ist. Dieser Modus ist mit der automatischen Skalierung kompatibel, die von .NET Compact Framework unterstützt wird, wodurch eine einfachere Anwendungsmigration ermöglicht wird.

  • Kompatibilität mit Layout-Managern wie FlowLayoutPanel und TableLayoutPanel wurde der Implementierung der automatischen Skalierung hinzugefügt.

  • Skalierungsfaktoren werden jetzt als Gleitkommawerte dargestellt, wozu üblicherweise die SizeF-Struktur verwendet wird, sodass Rundungsfehler so gut wie eliminiert sind.

Achtung

Beliebige Kombinationen aus DPI- und Schriftartskalierungsmodi werden nicht unterstützt. Obwohl Sie ein Benutzersteuerelement mithilfe eines Modus (z. B. DPI) skalieren und ohne Probleme auf einem Formular platzieren können, für das ein anderer Modus (Schriftart) verwendet wird, kann es zu unerwarteten Ergebnissen kommen, wenn Sie ein Grundformular in einem Modus mit einem abgeleiteten Formular in einem anderen Modus mischen.

Automatische Skalierung in der Praxis

Windows Forms verwendet jetzt die folgende Logik, um Formulare und deren Inhalte automatisch zu skalieren:

  1. Zur Entwurfszeit speichert jede ContainerControl-Instanz den Skalierungsmodus und ihre aktuelle Auflösung in der AutoScaleMode- bzw. der AutoScaleDimensions-Eigenschaft.

  2. Zur Laufzeit wird die tatsächliche Auflösung in der CurrentAutoScaleDimensions-Eigenschaft gespeichert. Die AutoScaleFactor-Eigenschaft berechnet dynamisch das Verhältnis zwischen der Laufzeit- und der Entwurfszeitskalierungsauflösung.

  3. Wenn das Formular geladen wird und sich die Werte von CurrentAutoScaleDimensions und AutoScaleDimensions unterscheiden, wird die PerformAutoScale-Methode aufgerufen, um das Steuerelement und dessen untergeordneten Elemente zu skalieren. Diese Methode übergeht das Layout und ruft die Scale-Methode auf, um die tatsächliche Skalierung auszuführen. Danach wird der Wert von AutoScaleDimensions aktualisiert, um weitere Skalierung zu vermeiden.

  4. PerformAutoScale wird auch in den folgenden Situationen automatisch aufgerufen:

    • Als Reaktion auf das OnFontChanged-Ereignis, wenn der Skalierungsmodus gleich Font ist.

    • Wenn wieder das Layout des Containersteuerelements verwendet wird und eine Änderung in der AutoScaleDimensions- oder der AutoScaleMode-Eigenschaft erkannt wurde.

    • Wenn, wie soeben erwähnt, ein übergeordnetes ContainerControl skaliert wird. Jedes Containersteuerelement muss seine untergeordneten Elemente mit seinen eigenen Skalierungsfaktoren skalieren, es darf dafür nicht den Faktor seines übergeordneten Containers verwenden.

  5. Untergeordnete Steuerelemente können ihr Skalierungsverhalten auf mehrere Arten ändern:

    • Die ScaleChildren-Eigenschaft kann überschrieben werden, um zu bestimmen, ob die untergeordneten Steuerelemente skaliert werden sollen oder nicht.

    • Die GetScaledBounds-Methode kann überschrieben werden, um die Begrenzungen für die Skalierung des Steuerelements, aber nicht die Skalierungslogik anzupassen.

    • Die ScaleControl-Methode kann überschrieben werden, um die Skalierungslogik für das aktuelle Steuerelement zu ändern.

Siehe auch