本記事では主に2つの問題を解決します
- C# Winform 高DPIにおけるフォントのぼやけ
- 高DPI(ズーム > 100%)でUIデザイナーが常に「100%に縮小」と促し、100%に戻さないとコントロールが飛び回る問題


テストプログラムの作成
- 新しい .NET Windows フォームアプリ(Winform)プロジェクトを作成

- .NET 6.0 を選択

- フォームサイズを 1000 x 1000 に設定(後でスケーリングが正しいか確認するため)

- ボタンを追加し、サイズを 150 x 50 に設定

- ピクチャーボックスを追加し、サイズを 300 x 300 に設定、右クリックで画像をインポート


- テストコードを追加
namespace WinFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Text = this.Width + "x" + this.Height + " pic "+ pictureBox1.Width + "x" + pictureBox1.Height + 起動環境();
}
public static string 起動環境()
{
#if NET461
return (".NET Framework 4.6.1");
#elif NET6_0
return (".NET6");
#endif
}
}
}
- 実行して効果を確認:net6 で実行するとサイズはすべて正しい

本格的に開始
- プロジェクトを右クリックし、アプリケーションマニフェスト
app.manifestを追加。ファイル名はデフォルトのまま、修正

次の部分のコメントを解除して、DPI 認識を有効化
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>
- プロジェクト名をダブルクリックして、構成ファイルを編集
TargetFrameworks をデュアルターゲットフレームワークに変更:<TargetFrameworks>net6.0-windows;net461;</TargetFrameworks>、保存後はプロジェクトの再読み込みを促されます。VS を一度閉じてからもう一度開くことをお勧めします。
完全なファイルは以下の通り
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFrameworks>net6.0-windows;net461;</TargetFrameworks>
<UseWindowsForms>true</UseWindowsForms>
<ApplicationManifest>app.manifest</ApplicationManifest>
<ApplicationVisualStyles>true</ApplicationVisualStyles>
<ApplicationUseCompatibleTextRendering>false</ApplicationUseCompatibleTextRendering>
<ApplicationHighDpiMode>SystemAware</ApplicationHighDpiMode>
</PropertyGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>
- コントロールが見つからないと警告された場合は、Form1.Designer.cs と Form1.cs に以下を追加
using System;
using System.Windows.Forms;
Program.csでApplicationConfiguration.Initialize();をコメントアウト実行時に
net461を選択
備考:私の画面は 2800 x 1800、ズーム 175%

やはり、表示サイズが正しくない

- Form1.cs に
AutoScaleMode = AutoScaleMode.Dpi;を追加
public Form1()
{
AutoScaleMode = AutoScaleMode.Dpi; // この行を追加。'InitializeComponent();' の上に置くこと
InitializeComponent();
}
再度実行

完璧!
- フォームをダブルクリックして編集しても、100% ズームの警告は表示されない。標準メニューと DataGridView を追加してテスト

完璧!二重の喜び!
まとめ
- 新しい .NET Windows フォームアプリ(Winform)プロジェクト [.NET 6.0] を作成
- アプリケーションマニフェスト
app.manifestを追加し、DPI 認識を有効化 TargetFrameworksをデュアルターゲットフレームワークに変更:<TargetFrameworks>net6.0-windows;net461;</TargetFrameworks>Program.csでApplicationConfiguration.Initialize();をコメントアウトAutoScaleMode = AutoScaleMode.Dpi;// この行を追加。'InitializeComponent();' の上に置くこと
既存のプロジェクトも projet ファイルを編集することでこの新しいプロジェクト形式にアップグレードでき、本記事で説明した機能をサポートできます。続きのチュートリアルが必要な場合はコメントでお知らせください。ここ数日はバケーション中です。今日はここまで。また次回お会いしましょう!
対応する DEMO