次の方法で共有


Windows フォームでの自動スケーリング

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

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

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

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

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

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

自動スケーリングの元のサポート

.NET Framework のバージョン 1.0 および 1.1 は、Windows の UI に使用される (Win32 SDK 値 DEFAULT_GUI_FONT で表す) 既定のフォントに依存した、簡単な方法で自動スケーリングをサポートしていました。 このフォントは通常、表示解像度が変更されたときにのみ変更されます。 自動スケーリングを実装するには、次のメカニズムが使用されました。

  1. デザイン時に、AutoScaleBaseSize プロパティ (現在は非推奨) は、開発者のコンピューター上の既定のシステム フォントの高さと幅に設定されていました。

  2. 実行時に、ユーザーのコンピューターの既定のシステム フォントを使用して、Form クラスの Font プロパティを初期化しました。

  3. フォームを表示する前に、ApplyAutoScaling メソッドを呼び出してフォームをスケーリングしました。 このメソッドは、AutoScaleBaseSize から相対的なスケール サイズを計算し、Font フォームとその子を実際にスケーリングする Scale メソッドを呼び出しました。

  4. ApplyAutoScaling の後続の呼び出しでフォームのサイズが徐々に変更されないように、AutoScaleBaseSize の値が更新されました。

このメカニズムはほとんどの目的で十分でしたが、次の制限が適用されていました。

  • AutoScaleBaseSize プロパティはベースライン のフォント サイズを整数値として表しているため、フォームが複数の解像度を循環すると、丸めエラーが発生します。

  • 自動スケーリングは、ContainerControl クラスではなく、Form クラスでのみ実装されました。 その結果、ユーザー コントロールは、ユーザー コントロールがフォームと同じ解像度でデザインされ、デザイン時にフォームに配置された場合にのみ、正しくスケーリングされます。

  • フォームとその子コントロールは、コンピューターの解像度が同じ場合にのみ、複数の開発者が同時に設計できます。 同様に、親フォームに関連する解像度にフォームの継承が依存するようにしました。

  • FlowLayoutPanelTableLayoutPanelなど、.NET Framework バージョン 2.0 で導入された新しいレイアウト マネージャーとは互換性がありません。

  • .NET Compact Framework との互換性に必要な表示解像度に基づく直接のスケーリングはサポートされていませんでした。

このメカニズムは、下位互換性を維持するために .NET Framework バージョン 2.0 で保持されますが、次に説明するより堅牢なスケーリング メカニズムに置き換わりました。 その結果、AutoScaleApplyAutoScalingAutoScaleBaseSize、および特定の Scale オーバーロードは古いものとしてマークされます。

手記

レガシ コードを .NET Framework バージョン 2.0 にアップグレードするときに、これらのメンバーへの参照を安全に削除できます。

自動スケーリングの現在のサポート

.NET Framework バージョン 2.0 では、Windows フォームの自動スケーリングに次の変更を加えることで、以前の制限を克服しています。

  • スケーリングの基本サポートが ContainerControl クラスに移動され、フォーム、ネイティブ複合コントロール、およびユーザー コントロールはすべて、均一なスケーリングサポートを受け取ります。 新しいメンバー AutoScaleFactorAutoScaleDimensionsAutoScaleMode、および PerformAutoScale が追加されました。

  • また、Control クラスには、スケーリングに参加したり、同じフォームでの混合スケーリングをサポートしたりするための新しいメンバーがいくつか用意されています。 具体的には、ScaleScaleChildren、および GetScaledBounds メンバーはスケーリングをサポートします。

  • AutoScaleMode 列挙型で定義されているシステム フォントのサポートを補完するために、画面解像度に基づくスケーリングのサポートが追加されました。 このモードは、.NET Compact Framework でサポートされている自動スケーリングと互換性があり、アプリケーションの移行が容易になります。

  • 自動スケーリングの実装には、FlowLayoutPanelTableLayoutPanel などのレイアウト マネージャーとの互換性が追加されました。

  • スケーリング係数は浮動小数点値として表されるようになりました。通常は SizeF 構造を使用するため、丸め誤差は実質的に排除されています。

注意

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

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

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

  1. 設計時に、各 ContainerControl はスケーリング モードと現在の解像度をそれぞれ AutoScaleMode および AutoScaleDimensionsに記録します。

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

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

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

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

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

    • 上記に示すように、親の ContainerControl がスケーリングされたとき。 各コンテナー コントロールは、親コンテナーからのスケーリング ファクターではなく、独自のスケーリング ファクターを使用してその子のスケーリングを担当します。

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

    • ScaleChildren プロパティをオーバーライドして、子コントロールをスケーリングすべきかどうかを決定することができます。

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

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

関連項目