用途
wpf-high-dpi-analyzer 用于分析和修复 WPF 应用程序的高 DPI 支持问题。它识别 DPI 相关缺陷,并针对每显示器 DPI 感知、位图缩放以及高分辨率显示器上的布局问题提供修复方案。
主要能力
- 检测 DPI 感知配置问题
- 查找硬编码像素值
- 识别位图缩放问题
- 检查每显示器 DPI 支持
- 分析变换与布局问题
- 审查 app.manifest 中的 DPI 设置
- 为常见 DPI 问题生成修复
- 测试多显示器 DPI 场景
使用方式
该技能通过输入 Schema 接收参数:
projectPath(必填,字符串):WPF 项目路径targetDpiMode(枚举,默认per-monitor-v2):可选system、per-monitor、per-monitor-v2checkCategories(数组,默认["manifest", "hardcoded-pixels", "bitmaps", "layouts"]):可选manifest、hardcoded-pixels、bitmaps、layouts、transforms、fontsgenerateFixes(布尔,默认true)
输出 Schema 包含:
success(布尔)dpiMode(字符串)issues(数组):每项包含severity(critical/high/medium/low)、category、file、line、description、fixrecommendations(字符串数组)
DPI 感知模式
System DPI Aware(旧版)
<!-- app.manifest -->
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
Per-Monitor DPI Aware(Windows 8.1+)
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
</windowsSettings>
</application>
Per-Monitor V2 DPI Aware(Windows 10 1703+)
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</windowsSettings>
</application>
常见问题与修复
硬编码像素值
<!-- BAD: Hardcoded pixels -->
<Button Width="100" Height="30"/>
<Grid Margin="10,5,10,5"/>
<TextBlock FontSize="12"/>
<!-- GOOD: Use device-independent units or relative sizing -->
<Button MinWidth="80" MinHeight="24" Padding="16,4"/>
<Grid Margin="{StaticResource StandardMargin}"/>
<TextBlock Style="{StaticResource BodyTextStyle}"/>
位图图像
<!-- BAD: Single resolution bitmap -->
<Image Source="icon.png"/>
<!-- GOOD: Use vector or provide multiple resolutions -->
<Image>
<Image.Source>
<DrawingImage>
<!-- Vector drawing -->
</DrawingImage>
</Image.Source>
</Image>
<!-- Or use BitmapScalingMode for crisp scaling -->
<Image Source="icon.png"
RenderOptions.BitmapScalingMode="HighQuality"/>
动态 DPI 处理
// Handle DPI changes at runtime
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// Get current DPI
var dpiScale = VisualTreeHelper.GetDpi(this);
Debug.WriteLine($"DPI: {dpiScale.PixelsPerDip * 96}");
}
protected override void OnDpiChanged(DpiScale oldDpi, DpiScale newDpi)
{
base.OnDpiChanged(oldDpi, newDpi);
// Handle DPI change
Debug.WriteLine($"DPI changed from {oldDpi.PixelsPerDip * 96} to {newDpi.PixelsPerDip * 96}");
// Reload high-DPI assets if needed
ReloadAssets(newDpi);
}
private void ReloadAssets(DpiScale dpi)
{
// Load appropriate resolution assets
var scale = dpi.PixelsPerDip;
string suffix = scale >= 2 ? "@2x" : scale >= 1.5 ? "@1.5x" : "";
// Load assets with suffix
}
}
Per-Monitor V2 设置
// App.xaml.cs
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
// Enable Per-Monitor V2 DPI awareness (Windows 10 1703+)
if (Environment.OSVersion.Version >= new Version(10, 0, 15063))
{
// Per-Monitor V2 is automatic with manifest, but verify
var awareness = GetProcessDpiAwareness();
Debug.WriteLine($"DPI Awareness: {awareness}");
}
base.OnStartup(e);
}
[DllImport("shcore.dll")]
private static extern int GetProcessDpiAwareness(IntPtr hprocess, out int awareness);
private static int GetProcessDpiAwareness()
{
GetProcessDpiAwareness(IntPtr.Zero, out int awareness);
return awareness;
}
}
变换问题
// BAD: Manual scaling calculations
var scale = 96.0 / GetSystemDpi();
transform.ScaleX = scale;
transform.ScaleY = scale;
// GOOD: Let WPF handle scaling
// Use device-independent units, WPF handles the rest
<Canvas>
<Rectangle Canvas.Left="10" Canvas.Top="10"
Width="100" Height="50"/>
</Canvas>
字体缩放
<!-- BAD: Hardcoded font size -->
<TextBlock FontSize="14"/>
<!-- GOOD: Use named styles or relative sizing -->
<TextBlock Style="{DynamicResource MaterialDesignBody1TextBlock}"/>
<!-- Or use system font size -->
<TextBlock FontSize="{x:Static SystemFonts.MessageFontSize}"/>
项目配置
<!-- .csproj -->
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
<!-- Enable high DPI support -->
<ApplicationHighDpiMode>PerMonitorV2</ApplicationHighDpiMode>
</PropertyGroup>
<!-- Include app.manifest -->
<ItemGroup>
<None Update="app.manifest">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
测试多 DPI
# Change display scaling via PowerShell (requires restart)
Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "LogPixels" -Value 144 # 150%
# Test with multiple monitors at different DPIs
# Use Windows display settings to set different scales per monitor
最佳实践
- 使用 Per-Monitor V2:Windows 10+ 上最佳的缩放支持
- 避免硬编码像素:使用相对或自动尺寸
- 使用矢量图形:图标使用 SVG 或 DrawingImage
- 提供多分辨率位图:@1x、@1.5x、@2x
- 处理 OnDpiChanged:DPI 变化时重新加载资源
- 在多个 DPI 级别测试:100%、125%、150%、200%
相关技能
- wpf-xaml-style-generator - DPI 感知样式
- desktop-accessibility process - 无障碍测试
- visual-regression-setup - 不同 DPI 下的视觉测试
相关智能体
- wpf-dotnet-expert - WPF 专业知识
- desktop-ux-analyst - UX 审查
限制
资料未提供该技能的收费、价格、平台支持范围、具体安装命令及性能指标等信息。