| name | wpf-high-dpi-analyzer |
| description | Analyze and fix WPF applications for high DPI support, per-monitor DPI awareness, and scaling issues |
| allowed-tools | Read, Grep, Glob, Bash |
| tags | ["wpf","dpi","scaling","accessibility","windows"] |
| graph | {"domains":["domain:software-engineering"],"specializations":["specialization:desktop-development"],"skillAreas":["skill-area:desktop-ui-frameworks","skill-area:performance-monitoring-profiling"],"roles":["role:desktop-developer","role:fullstack-engineer"],"workflows":["workflow:feature-development","workflow:release-management"]} |
wpf-high-dpi-analyzer
Analyze and fix WPF applications for high DPI support. This skill identifies DPI-related issues and provides fixes for per-monitor DPI awareness, bitmap scaling, and layout problems on high-resolution displays.
Capabilities
- Detect DPI awareness configuration issues
- Find hardcoded pixel values
- Identify bitmap scaling problems
- Check for per-monitor DPI support
- Analyze transform and layout issues
- Review app.manifest DPI settings
- Generate fixes for common DPI problems
- Test multi-monitor DPI scenarios
Input Schema
{
"type": "object",
"properties": {
"projectPath": {
"type": "string",
"description": "Path to the WPF project"
},
"targetDpiMode": {
"enum": ["system", "per-monitor", "per-monitor-v2"],
"default": "per-monitor-v2"
},
"checkCategories": {
"type": "array",
"items": {
"enum": ["manifest", "hardcoded-pixels", "bitmaps", "layouts", "transforms", "fonts"]
},
"default": ["manifest", "hardcoded-pixels", "bitmaps", "layouts"]
},
"generateFixes": {
"type": "boolean",
"default": true
}
},
"required": ["projectPath"]
}
Output Schema
{
"type": "object",
"properties": {
"success": { "type": "boolean" },
"dpiMode": { "type": "string" },
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"severity": { "enum": ["critical", "high", "medium", "low"] },
"category":
DPI Awareness Modes
System DPI Aware (Legacy)
<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>
Common Issues and Fixes
Hardcoded Pixel Values
<Button Width="100" Height="30"/>
<Grid Margin="10,5,10,5"/>
<TextBlock FontSize="12"/>
<Button MinWidth="80" MinHeight="24" Padding="16,4"/>
<Grid Margin="{StaticResource StandardMargin}"/>
<TextBlock Style="{StaticResource BodyTextStyle}"/>
Bitmap Images
<Image Source="icon.png"/>
<Image>
<Image.Source>
<DrawingImage>
</DrawingImage>
</Image.Source>
</Image>
<Image Source="icon.png"
RenderOptions.BitmapScalingMode="HighQuality"/>
Dynamic DPI Handling
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var dpiScale = VisualTreeHelper.GetDpi(this);
Debug.WriteLine($"DPI: {dpiScale.PixelsPerDip * 96}");
}
protected override void OnDpiChanged(DpiScale oldDpi, DpiScale newDpi)
{
base.OnDpiChanged(oldDpi, newDpi);
Debug.WriteLine($"DPI changed from {oldDpi.PixelsPerDip * 96} to {newDpi.PixelsPerDip * 96}");
ReloadAssets(newDpi);
}
private void ReloadAssets(DpiScale dpi)
{
var scale = dpi.PixelsPerDip;
string suffix = scale >= 2 ? "@2x" : scale >= 1.5 ? "@1.5x" : "";
}
}
Per-Monitor V2 Setup
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
if (Environment.OSVersion.Version >= new Version(10, 0, 15063))
{
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;
}
}
Transform Issues
var scale = 96.0 / GetSystemDpi();
transform.ScaleX = scale;
transform.ScaleY = scale;
<Canvas>
<Rectangle Canvas.Left="10" Canvas.Top="10"
Width="100" Height="50"/>
</Canvas>
Font Scaling
<TextBlock FontSize="14"/>
<TextBlock Style="{DynamicResource MaterialDesignBody1TextBlock}"/>
<TextBlock FontSize="{x:Static SystemFonts.MessageFontSize}"/>
Project Configuration
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
<ApplicationHighDpiMode>PerMonitorV2</ApplicationHighDpiMode>
</PropertyGroup>
<ItemGroup>
<None Update="app.manifest">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
Testing Multi-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
Best Practices
- Use Per-Monitor V2: Best scaling support on Windows 10+
- Avoid hardcoded pixels: Use relative or auto sizing
- Use vector graphics: SVG or DrawingImage for icons
- Provide multi-resolution bitmaps: @1x, @1.5x, @2x
- Handle OnDpiChanged: Reload assets when DPI changes
- Test at multiple DPI levels: 100%, 125%, 150%, 200%
Related Skills
wpf-xaml-style-generator - DPI-aware styles
desktop-accessibility process - Accessibility testing
visual-regression-setup - Visual testing at different DPIs
Related Agents
wpf-dotnet-expert - WPF expertise
desktop-ux-analyst - UX review