Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Assist migration from WPF to WinUI 3 / Windows App SDK with code transformation and compatibility guidance
.claude/skills/a5c-ai-winui3-migration-helper/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 78% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 42% | 0% |
| case-03 | ✗→✓ | ▲ Improved | -5% | 0% |
| case-17 | ✗→✓ | ▲ Improved | 151% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 116% | 0% |
Assist migration from WPF to WinUI 3 / Windows App SDK. This skill analyzes WPF applications and provides migration paths, code transformations, and compatibility guidance for modernizing to WinUI 3.
json{ "type": "object", "properties": { "projectPath": { "type": "string", "description": "Path to the WPF project" }, "migrationStrategy": { "enum": ["full", "incremental", "analysis-only"], "default": "analysis-only" }, "targetSdk": { "type": "string", "default": "1.5", "description": "Target Windows App SDK version" }, "preserveWpfComponents": { "type": "array", "items": { "type": "string" }, "description": "WPF components to keep via XAML Islands" }, "generateReport": { "type": "boolean", "default": true } }, "required": ["projectPath"] }
json{ "type": "object", "properties": { "success": { "type": "boolean" }, "compatibility": { "type": "object", "properties": { "score": { "type": "number" }, "blockers": { "type": "array" }, "warnings": { "type": "array" } } }, "migrationTasks": { "type": "array", "items": { "type": "object", "properties": { "category": { "type": "string" }, "task": { "type": "string" }, "effort": { "enum": ["low", "medium", "high"] }, "automated": { "type": "boolean" } } } }, "codeTransformations": { "type": "array", "items": { "type": "object", "properties": { "file": { "type": "string" }, "original": { "type": "string" }, "transformed": { "type": "string" } } } } }, "required": ["success"] }
| WPF | WinUI 3 | |-----|---------| | System.Windows | Microsoft.UI.Xaml | | System.Windows.Controls | Microsoft.UI.Xaml.Controls | | System.Windows.Media | Microsoft.UI.Xaml.Media | | System.Windows.Input | Microsoft.UI.Xaml.Input | | System.Windows.Data | Microsoft.UI.Xaml.Data |
xml<!-- WPF --> <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <!-- WinUI 3 --> <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:MyApp">
csharp// WPF public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } } // WinUI 3 public sealed partial class MainWindow : Window { public MainWindow() { this.InitializeComponent(); // WinUI 3: No automatic window sizing this.SetWindowSize(800, 600); } private void SetWindowSize(int width, int height) { var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this); var windowId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(hWnd); var appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId); appWindow.Resize(new Windows.Graphics.SizeInt32(width, height)); } }
xml<!-- WPF: DataGrid --> <DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Header="Name" Binding="{Binding Name}"/> </DataGrid.Columns> </DataGrid> <!-- WinUI 3: Community Toolkit DataGrid --> <toolkit:DataGrid ItemsSource="{x:Bind ViewModel.Items}" AutoGenerateColumns="False"> <toolkit:DataGrid.Columns> <toolkit:DataGridTextColumn Header="Name" Binding="{Binding Name}"/> </toolkit:DataGrid.Columns> </toolkit:DataGrid>
xml<!-- WPF: Classic binding --> <TextBlock Text="{Binding Name}"/> <Button Command="{Binding SaveCommand}"/> <!-- WinUI 3: x:Bind (compiled bindings, recommended) --> <TextBlock Text="{x:Bind ViewModel.Name, Mode=OneWay}"/> <Button Command="{x:Bind ViewModel.SaveCommand}"/> <!-- WinUI 3: Classic binding still works --> <TextBlock Text="{Binding Name}"/>
xml<!-- WPF --> <ResourceDictionary> <SolidColorBrush x:Key="AccentBrush" Color="#0078D4"/> <Style TargetType="Button"> <Setter Property="Background" Value="{StaticResource AccentBrush}"/> </Style> </ResourceDictionary> <!-- WinUI 3 --> <ResourceDictionary> <SolidColorBrush x:Key="AccentBrush" Color="#0078D4"/> <Style TargetType="Button"> <Setter Property="Background" Value="{StaticResource AccentBrush}"/> </Style> </ResourceDictionary> <!-- Note: Largely compatible, but some default styles differ -->
xml<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>WinExe</OutputType> <TargetFramework>net8.0-windows</TargetFramework> <UseWPF>true</UseWPF> </PropertyGroup> </Project>
xml<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>WinExe</OutputType> <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework> <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion> <UseWinUI>true</UseWinUI> <WindowsPackageType>None</WindowsPackageType> <Platforms>x64;x86;arm64</Platforms> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.240227000"/> <PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.756"/> </ItemGroup> </Project>
| Feature | Alternative | |---------|-------------| | NavigationWindow | Custom navigation with Frame | | DataGrid (built-in) | Community Toolkit DataGrid | | RichTextBox | RichEditBox | | WebBrowser | WebView2 | | WindowsFormsHost | Not available (use XAML Islands in reverse) | | System tray icons | Win32 APIs directly |
| WPF Feature | WinUI 3 Approach | |-------------|------------------| | Application.Current.Dispatcher | DispatcherQueue | | RoutedUICommand | ICommand implementation | | Triggers in styles | VisualStateManager | | Effect (blur, etc.) | Composition APIs | | DynamicResource | StaticResource (mostly) |
csharp// WPF Application.Current.Dispatcher.Invoke(() => { // UI code }); // WinUI 3 DispatcherQueue.GetForCurrentThread().TryEnqueue(() => { // UI code });
xml<!-- WPF: Style Trigger --> <Style TargetType="Button"> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" Value="LightBlue"/> </Trigger> </Style.Triggers> </Style> <!-- WinUI 3: VisualStateManager --> <Style TargetType="Button"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Border x:Name="RootBorder" Background="{TemplateBinding Background}"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="PointerOver"> <Storyboard> <ColorAnimation Storyboard.TargetName="RootBorder" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="LightBlue"/> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <ContentPresenter/> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>
wpf-mvvm-scaffold - MVVM pattern (works in both)msix-package-generator - WinUI 3 packagingdesktop-migration process - Full migration workflowwpf-dotnet-expert - WPF expertisedesktop-migration-strategist - Migration planning| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 16,983 | 16,790 | -1% | 1 | 1 | 0% | 3,688 | 6,553 | +78% | 0 | 0 | — |
case-02 | fail→pass | 20,443 | 21,071 | +3% | 1 | 1 | 0% | 4,325 | 6,137 | +42% | 0 | 0 | — |
case-03 | fail→pass | 25,669 | 13,383 | -48% | 1 | 1 | 0% | 5,837 | 5,539 | -5% | 0 | 0 | — |
case-04 | pass→pass | 8,430 | 6,177 | -27% | 1 | 1 | 0% | 1,815 | 3,835 | +111% | 0 | 0 | — |
case-05 | pass→pass | 8,635 | 4,573 | -47% | 1 | 1 | 0% | 1,709 | 3,379 | +98% | 0 | 0 | — |
case-06 | pass→pass | 13,080 | 9,503 | -27% | 1 | 1 | 0% | 2,661 | 4,499 | +69% | 0 | 0 | — |
case-07 | pass→pass | 9,983 | 5,509 | -45% | 1 | 1 | 0% | 2,030 | 3,505 | +73% | 0 | 0 | — |
case-08 | pass→pass | 10,038 | 7,424 | -26% | 1 | 1 | 0% | 1,884 | 3,914 | +108% | 0 | 0 | — |
case-09 | pass→pass | 6,760 | 6,268 | -7% | 1 | 1 | 0% | 1,250 | 3,469 | +178% | 0 | 0 | — |
case-10 | pass→pass | 5,480 | 5,334 | -3% | 1 | 1 | 0% | 1,012 | 3,479 | +244% | 0 | 0 | — |
case-11 | fail→fail | 15,235 | 9,750 | -36% | 1 | 1 | 0% | 2,727 | 4,258 | +56% | 0 | 0 | — |
case-12 | pass→pass | 13,224 | 8,624 | -35% | 1 | 1 | 0% | 2,286 | 4,173 | +83% | 0 | 0 | — |
case-13 | pass→pass | 17,682 | 9,088 | -49% | 1 | 1 | 0% | 2,099 | 4,154 | +98% | 0 | 0 | — |
case-14 | pass→pass | 11,795 | 9,367 | -21% | 1 | 1 | 0% | 2,377 | 4,022 | +69% | 0 | 0 | — |
case-15 | pass→pass | 14,459 | 7,362 | -49% | 1 | 1 | 0% | 2,548 | 3,724 | +46% | 0 | 0 | — |
case-16 | pass→pass | 6,834 | 4,016 | -41% | 1 | 1 | 0% | 1,157 | 3,081 | +166% | 0 | 0 | — |
case-17 | fail→pass | 5,458 | 2,188 | -60% | 1 | 1 | 0% | 1,170 | 2,942 | +151% | 0 | 0 | — |
case-18 | fail→pass | 11,014 | 6,891 | -37% | 1 | 1 | 0% | 1,886 | 4,071 | +116% | 0 | 0 | — |
case-19 | fail→fail | 10,943 | 8,128 | -26% | 1 | 1 | 0% | 2,019 | 3,979 | +97% | 0 | 0 | — |
case-20 | pass→pass | 10,579 | 10,142 | -4% | 1 | 1 | 0% | 2,418 | 4,736 | +96% | 0 | 0 | — |
case-21 | pass→pass | 14,586 | 12,642 | -13% | 1 | 1 | 0% | 3,287 | 5,370 | +63% | 0 | 0 | — |
case-22 | pass→pass | 9,288 | 6,130 | -34% | 1 | 1 | 0% | 1,956 | 3,798 | +94% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +23 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.