Babysitter wpf-high-dpi-analyzer
Analyze and fix WPF applications for high DPI support, per-monitor DPI awareness, and scaling issues
install
source · Clone the upstream repo
git clone https://github.com/a5c-ai/babysitter
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/a5c-ai/babysitter "$T" && mkdir -p ~/.claude/skills && cp -r "$T/library/specializations/desktop-development/skills/wpf-high-dpi-analyzer" ~/.claude/skills/a5c-ai-babysitter-wpf-high-dpi-analyzer && rm -rf "$T"
manifest:
library/specializations/desktop-development/skills/wpf-high-dpi-analyzer/SKILL.mdsource content
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": { "type": "string" }, "file": { "type": "string" }, "line": { "type": "number" }, "description": { "type": "string" }, "fix": { "type": "string" } } } }, "recommendations": { "type": "array", "items": { "type": "string" } } }, "required": ["success", "issues"] }
DPI Awareness Modes
System DPI Aware (Legacy)
<!-- 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>
Common Issues and Fixes
Hardcoded Pixel Values
<!-- 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}"/>
Bitmap Images
<!-- 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"/>
Dynamic DPI Handling
// 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 Setup
// 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; } }
Transform Issues
// 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>
Font Scaling
<!-- 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}"/>
Project Configuration
<!-- .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>
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
- DPI-aware styleswpf-xaml-style-generator
process - Accessibility testingdesktop-accessibility
- Visual testing at different DPIsvisual-regression-setup
Related Agents
- WPF expertisewpf-dotnet-expert
- UX reviewdesktop-ux-analyst