Unterstützung hoher DPI-Werte in Windows Forms

Ab .NET Framework 4.7 enthält Windows Forms Verbesserungen für allgemeine Szenarien mit hohen und dynamischen DPI-Werten. Dazu gehören:

  • Verbesserungen bei der Skalierung und dem Layout einer Reihe von Windows Forms-Steuerelementen, z. B. dem Steuerelement MonthCalendar und dem Steuerelement CheckedListBox.

  • Single-Pass-Skalierung. In .NET Framework 4.6 und früheren Versionen erfolgte die Skalierung über mehrere Durchläufe, was dazu führte, dass einige Steuerelemente mehr skaliert wurden als erforderlich.

  • Unterstützung für dynamische DPI-Szenarien, in denen der Benutzer den DPI- oder Skalierungsfaktor ändert, nachdem eine Windows Forms-Anwendung gestartet wurde.

In .NET Framework-Versionen ab 4.7 ist die erweiterte Unterstützung hoher DPI-Werte ein Feature, das Sie abonnieren können. Sie müssen Ihre Anwendung so konfigurieren, dass sie dieses Feature nutzen kann.

Konfigurieren Ihrer Windows Forms-App für die Unterstützung hoher DPI-Werte

Die neuen Windows Forms-Features, die die Berücksichtigung hoher DPI-Werte unterstützen, sind nur in Anwendungen für .NET Framework 4.7 auf Windows-Betriebssystemen ab dem Windows 10 Creators Update verfügbar.

Darüber hinaus müssen Sie Folgendes tun, um die Unterstützung hoher DPI-Werte in Ihrer Windows Forms-Anwendung zu konfigurieren:

  • Deklarieren Sie die Kompatibilität mit Windows 10.

    Fügen Sie Ihrer Manifestdatei zu diesem Zweck Folgendes hinzu:

    <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
      <application>
        <!-- Windows 10 compatibility -->
        <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
      </application>
    </compatibility>
    
  • Aktivieren Sie die DPI-Berücksichtigung pro Monitor in der app.config-Datei.

    Windows Forms führt ein neues <System.Windows.Forms.ApplicationConfigurationSection>-Element ein, das neue Features und Anpassungen unterstützt, die ab .NET Framework 4.7 hinzugefügt wurden. Um die neuen Features für die Unterstützung hoher DPI-Werte zu nutzen, fügen Sie der Anwendungskonfigurationsdatei Folgendes hinzu.

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

    Wichtig

    In früheren Versionen von .NET Framework haben Sie das Manifest verwendet, um Unterstützung hoher DPI-Werte hinzuzufügen. Dieser Ansatz wird nicht mehr empfohlen, da in der app.config-Datei definierte Einstellungen überschrieben werden.

  • Rufen Sie die statische Methode EnableVisualStyles auf.

    Dies sollte der erste Methodenaufruf im Einstiegspunkt Ihrer Anwendung sein. Beispiel:

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

Deaktivieren einzelner Features für hohe DPI-Werte

Durch Festlegen des DpiAwareness-Werts auf PerMonitorV2 werden alle von .NET Framework-Versionen ab 4.7 unterstützten Features, die hohe DPI-Werte berücksichtigen, aktiviert. Dies ist normalerweise für die meisten Windows Forms-Anwendungen geeignet. Möglicherweise möchten Sie jedoch eine oder mehrere einzelne Features deaktivieren. Der wichtigste Grund dafür ist, dass dieses Feature von Ihrem vorhandenen Anwendungscode bereits behandelt wird. Wenn Ihre Anwendung beispielsweise die automatische Skalierung behandelt, können Sie das Feature für die automatische Größenänderung wie folgt deaktivieren:

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

Eine Liste der einzelnen Schlüssel und deren Werte finden Sie unter Windows Forms: Konfigurationselement hinzufügen.

Neue DPI-Änderungsereignisse

Ab .NET Framework 4.7 können Sie mithilfe von drei neuen Ereignissen dynamische DPI-Änderungen programmgesteuert behandeln:

  • DpiChangedAfterParent wird ausgelöst, wenn die DPI-Einstellung für ein Steuerelement programmgesteuert geändert wird, nachdem ein DPI-Änderungsereignis für das übergeordnete Steuerelement oder Formular aufgetreten ist.
  • DpiChangedBeforeParent wird ausgelöst, wenn die DPI-Einstellung für ein Steuerelement programmgesteuert geändert wird, bevor ein DPI-Änderungsereignis für das übergeordnete Steuerelement oder Formular auftritt.
  • DpiChanged wird ausgelöst, wenn die DPI-Einstellung auf dem Anzeigegerät, auf dem das Formular zurzeit angezeigt wird, geändert wird.

Neue Hilfsmethoden und -eigenschaften

.NET Framework 4.7 fügt außerdem eine Reihe neuer Hilfsmethoden und -eigenschaften hinzu, die Informationen zur DPI-Skalierung bereitstellen und es Ihnen ermöglichen, die DPI-Skalierung auszuführen. Dazu gehören:

Überlegungen zur Versionsverwaltung

Neben .NET Framework 4.7 und Windows 10 Creators Update kann Ihre Anwendung möglicherweise auch in Umgebungen ohne Kompatibilität mit den Verbesserungen zur Berücksichtigung hoher DPI-Werte ausgeführt werden. In diesem Fall müssen Sie einen Fallback für Ihre Anwendung entwickeln. Dazu können Sie benutzerdefinierte Zeichnung ausführen, um die Skalierung zu behandeln.

Dazu müssen Sie auch das Betriebssystem bestimmen, auf dem Ihre App ausgeführt wird. Sie können dies beispielsweise mit folgendem Code tun:

// Create a reference to the OS version of Windows 10 Creators Update.
Version OsMinVersion = new Version(10, 0, 15063, 0);

// Access the platform/version of the current OS.
Console.WriteLine(Environment.OSVersion.Platform.ToString());
Console.WriteLine(Environment.OSVersion.VersionString);

// Compare the current version to the minimum required version.
Console.WriteLine(Environment.OSVersion.Version.CompareTo(OsMinVersion));

Beachten Sie, dass Ihre Anwendung Windows 10 nicht erfolgreich erkennt, wenn es im Anwendungsmanifest nicht als unterstütztes Betriebssystem aufgeführt wurde.

Sie können auch die Version von .NET Framework überprüfen, für die die Anwendung erstellt wurde:

Console.WriteLine(AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName);

Weitere Informationen