自動スケーリング

自動スケーリングを使用すると、特定のディスプレイ解像度またはフォントを持つ 1 台のコンピューター上でデザインされたフォームとそのコントロールを、別のコンピューターで別のディスプレイ解像度またはフォントで適切に表示できます。 フォームとコントロールはインテリジェントにサイズ変更され、ユーザーと他の開発者の両方のマシン上のネイティブ ウィンドウや他のアプリケーションと一貫性を保ちます。 自動スケーリングとビジュアル スタイルは、Windows フォームアプリケーションが各ユーザーのコンピューター上のネイティブ Windows アプリケーションと比較して一貫した外観を維持するのに役立ちます。

ほとんどの場合、自動スケーリングは Windows フォームで想定どおりに動作します。 ただし、フォント パターンの変更は問題になる可能性があります。 この問題を解決する方法の例については、「方法: Windows フォーム アプリケーションのフォント パターンの変更に対応する」を参照してください。

.NETでの DPI 認識

DPI 認識は、既定でApplicationHighDpiModeに設定されている SystemAware プロパティを使用して、プロジェクト ファイルを通じて構成されます。 この構成は、アプリケーションの起動時に DPI 処理を自動的に構成するために、アプリケーション ブートストラップ システムと連携します。

Windows フォーム アプリケーションの既定の推奨 DPI モードはSystemAware。 このモードでは、アプリケーションの起動時に DPI 設定を 1 回クエリし、アプリケーションの有効期間中にその値を使用して、一貫したスケーリング動作を提供します。

プロジェクト ファイルで DPI モードを構成します。

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <ApplicationHighDpiMode>SystemAware</ApplicationHighDpiMode>
  </PropertyGroup>
</Project>

Note

推奨される方法は、プロジェクト ファイルを使用して DPI を構成することですが、アプリケーション マニフェスト ファイル (app.manifest) を使用してこれらの設定をオーバーライドすることもできます。 ただし、マニフェストを使用することは推奨されません。これは、アプリケーション構成との競合を引き起こす可能性があるためです。 詳細については、「 コンパイラの警告WFO0003」を参照してください。

Visual Studio デザイナーに関する考慮事項

Visual Studioでフォームを設計する場合は、デザイナーの DPI 認識をアプリケーションとは別に構成することが必要になる場合があります。 Visual Studio 2022 バージョン 17.8 以降では、プロジェクト ファイルで ForceDesignerDPIUnaware プロパティを設定して、Windows フォーム デザイナーを DPI 非対応モードで実行できます。 この設定は、高 DPI モニターでフォームを設計するときにレンダリングの問題を回避するのに役立ちます。

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <ForceDesignerDPIUnaware>true</ForceDesignerDPIUnaware>
  </PropertyGroup>
</Project>

このプロパティは、Visual Studio デザイナーにのみ影響し、アプリケーションの実行方法は変更されません。 詳細については、「 DPI 認識を無効にしてスケーリングの問題に対処する」を参照してください。

使用可能な DPI モードは次のとおりです。

  • SystemAware—アプリケーションは起動時に DPI に対して 1 回クエリを実行し、アプリの有効期間中にこの値を使用します。
  • PerMonitor—アプリケーションはモニターごとに DPI の変更をチェックし、DPI が変更されたときに再スケーリングします。
  • PerMonitorV2— PerMonitorと同様ですが、子ウィンドウの DPI 変更通知とスケーリング動作の改善が可能になります。
  • DpiUnaware—アプリケーションは DPI の変更に合わせてスケーリングせず、Windowsはスケーリングを処理します。
  • DpiUnawareGdiScaled DpiUnawareに似ていますが、GDI ベースのコンテンツの品質が向上します。

DPI 設定の構成の詳細については、「.NET 6 のWindows フォームの新機能」を参照してください。

自動スケーリングの必要性

自動スケーリングを使用しない場合、1 つのディスプレイ解像度またはフォント用に設計されたアプリケーションは、その解像度またはフォントが変更されたときに小さすぎるか、大きすぎるように見えます。 たとえば、Tahoma 9 ポイントをベースラインとして使用してアプリケーションを設計する場合、調整を行わないと、システム フォントが Tahoma 12 ポイントのコンピューターで実行すると小さすぎるように見えます。 タイトル、メニュー、テキスト ボックスの内容などのテキスト要素は、他のアプリケーションよりも小さくレンダリングされます。 さらに、タイトル バー、メニュー、多くのコントロールなど、テキストを含むユーザー インターフェイス (UI) 要素のサイズは、使用されるフォントによって異なります。 この例では、これらの要素も比較的小さく表示されます。

アプリケーションを特定のディスプレイ解像度用に設計すると、類似した状況が発生します。 最も一般的なディスプレイ解像度は 96 ドット/インチ (DPI) であり、100% ディスプレイスケーリングに相当しますが、125%、150%、200% (それぞれ 120、144、192 DPI) 以上をサポートする高解像度ディスプレイがより一般的になっています。 調整を行わないと、ある解像度用に設計されたアプリケーション(特にグラフィックスベースのもの)は、別の解像度で実行すると大きすぎるか小さすぎるように見えます。

自動スケーリングでは、相対フォント サイズまたは表示解像度に従ってフォームとその子コントロールのサイズを自動的に変更することで、これらの問題に対処します。 Windows オペレーティング システムでは、ダイアログ 単位と呼ばれる相対的な測定単位を使用したダイアログ ボックスの自動スケーリングがサポートされています。 ダイアログ ユニットはシステム フォントに基づいており、ピクセルとの関係は Win32 SDK 関数 GetDialogBaseUnitsによって決定できます。 ユーザーがWindowsで使用するテーマを変更すると、すべてのダイアログ ボックスがそれに応じて自動的に調整されます。 Windows フォームでは、既定のシステム フォントまたは表示解像度に従った自動スケーリングがサポートされます。 必要に応じて、アプリケーションで自動スケーリングを無効にすることができます。

注意事項

DPI モードとフォント スケーリング モードの任意の組み合わせはサポートされていません。 1 つのモード (DPI など) を使用してユーザー コントロールをスケーリングし、別のモード (Font) を使用してフォームに配置することもできますが、基本フォームを 1 つのモードで混在させ、別のモードで派生フォームを混在させると、予期しない結果が発生する可能性があります。

自動スケーリングが機能している

Windows フォームでは、次のロジックを使用して、フォームとその内容を自動的にスケーリングします。

  1. デザイン時に、各 ContainerControl は、スケーリング モードとその現在の解像度をそれぞれ AutoScaleMode プロパティと AutoScaleDimensions プロパティに記録します。

  2. 実行時に、実際の解像度は CurrentAutoScaleDimensions プロパティに格納されます。 AutoScaleFactor プロパティは、実行時とデザイン時のスケーリングの解像度の比率を動的に計算します。

  3. フォームが読み込まれるときに、 CurrentAutoScaleDimensions と AutoScaleDimensions の値が異なる場合は、 PerformAutoScale メソッドが呼び出され、コントロールとその子がスケーリングされます。 このメソッドはレイアウトを中断し、Scale メソッドを呼び出して実際のスケーリングを実行します。 その後、プログレッシブ スケーリングを回避するために、 AutoScaleDimensions の値が更新されます。

  4. PerformAutoScale は、次の状況でも自動的に呼び出されます。

    • スケーリング モードが OnFontChangedされている場合は、Font イベントに応答します。

    • コンテナー コントロールのレイアウトが再開され、AutoScaleDimensions プロパティまたは AutoScaleMode プロパティで変更が検出された場合。

    • 親 ContainerControl が拡大縮小されている場合。 各コンテナー コントロールは、親コンテナーからのスケーリング ファクターではなく、独自のスケーリング ファクターを使用してその子のスケーリングを担当します。

  5. 子供コントロールは、いくつかの方法でそのスケーリングの動作を変更することができます。

    • ScaleChildren プロパティをオーバーライドして、子コントロールをスケーリングする必要があるかどうかを判断します。

    • GetScaledBounds メソッドをオーバーライドして、コントロールのスケールの範囲を調整しますが、スケーリング ロジックは調整しません。

    • ScaleControl メソッドをオーバーライドして、現在のコントロールのスケーリング ロジックを変更します。

高DPI の機能強化

.NETには、特にPerMonitorV2 モードでの高 DPI レンダリングの大幅な改善が含まれています。

  • モニターごとの DPI 認識 — 異なる DPI 設定のモニター間を移動すると、アプリケーションが動的に調整されます。
  • スケーリング動作の改善 - 入れ子になったコントロールやコンテナー コントロール (.NET 6 以降) など、DPI が変更されたときにコントロールが正しくスケーリングされます。
  • フォーム サイズのスケーリング - MaximumSizeプロパティとMinimumSizeプロパティは、現在のモニター DPI 設定 (.NET 7 以降、既定では .NET 8 以降で有効) に基づいてスケーリングされます。
  • DPI 変更イベント - 新しいイベントを使用すると、動的な DPI 変更をプログラムで処理できます。
    • DpiChanged—フォームが現在表示されているディスプレイ デバイスで DPI 設定が変更されると発生します。
    • DpiChangedBeforeParent—親コントロールまたはフォームの DPI 変更イベントが発生する前に、コントロールの DPI 設定がプログラムによって変更されたときに発生します。
    • DpiChangedAfterParent—親コントロールまたはフォームの DPI 変更イベントが発生した後に、コントロールの DPI 設定がプログラムによって変更されたときに発生します。

高 DPI の機能強化の詳細については、「.NET 6 のWindows フォームの新機能」、.NET 7 のWindows フォームの新機能、および .NET 8 のWindows フォームの新機能を参照してください。

.NET フレームワークの違い

.NETフレームワークと.NETは、DPI 認識の処理方法が異なります。

  • .NET Framework で、要素を<System.Windows.Forms.ApplicationConfigurationSection> ファイルを使用して DPI 認識を構成します。
  • .NETで、ApplicationHighDpiMode プロパティを使用してプロジェクト ファイルを通じて DPI 認識を構成します。
  • .NET Framework は DPI 構成にマニフェスト ファイルを使用しますが、これは推奨されなくなりました。
  • .NETは、より優れたスケーリング動作と信頼性の高い DPI 変更処理を提供します。

.NET Framework DPI 構成の詳細については、Windows フォームでの高 DPI のサポートを参照してください。

こちらも参照ください