Source profileQuality 92/100

Postpartum-genushyacinthus29/dotnet-skills/skills/dotnet-wpf/SKILL.md

dotnet-wpf

Build and modernize WPF applications on .NET with correct XAML, data binding, commands, threading, styling, and Windows desktop migration decisions.

Source repository stars
9
Declared platforms
0
Static risk flags
1
Last source update
2026-08-26
Source checked
2026-08-28

Decision brief

What it does: where it fits

Build and modernize WPF applications on . NET with correct XAML, data binding, commands, threading, styling, and Windows desktop migration decisions.

Best for

    Not for

    • Tasks that require unconfirmed production actions or broad system permissions.
    • Environments where the pinned source and install steps cannot be inspected.

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeNot declaredNo explicit evidencePortability before use
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/Postpartum-genushyacinthus29/dotnet-skills --skill "skills/dotnet-wpf"
    Safe inspection promptEditorial

    Inspect the Agent Skill "dotnet-wpf" from https://github.com/Postpartum-genushyacinthus29/dotnet-skills/blob/e520b1e9a27485d8b5f3ec0b71dfcd85ab371a40/skills/dotnet-wpf/SKILL.md at commit e520b1e9a27485d8b5f3ec0b71dfcd85ab371a40. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

      Workflow

      1. Confirm Windows-only scope — WPF is Windows-only even when the wider .NET stack is cross-platform 2. Apply MVVM pattern — keep views dumb, logic in ViewModels, use commands 3. Manage data binding explicitly — choose correct binding modes, validate at runtime 4. Use styles and…

      Confirm Windows-only scope — WPF is Windows-only even when the wider .NET stack is cross-platformApply MVVM pattern — keep views dumb, logic in ViewModels, use commandsManage data binding explicitly — choose correct binding modes, validate at runtime
    2. 02

      Trigger On

      working on WPF UI, MVVM, binding, commands, or desktop modernization

      working on WPF UI, MVVM, binding, commands, or desktop modernizationmigrating WPF from .NET Framework to .NETintegrating newer Windows capabilities into a WPF app
    3. 03

      Documentation

      WPF Overview

      WPF OverviewData Binding OverviewMVVM Toolkit Introduction
    4. 04

      Project Structure

      Review the “Project Structure” section in the pinned source before continuing.

      Review and apply the “Project Structure” source section.
    5. 05

      MVVM Pattern

      Review the “MVVM Pattern” section in the pinned source before continuing.

      Review and apply the “MVVM Pattern” source section.

    Permission review

    Static risk signals and limitations

    Network access

    medium · line 104

    The documentation includes network, browsing, or remote request actions.

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    Network access

    medium · line 105

    The documentation includes network, browsing, or remote request actions.

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score92/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars9SourceRepository attention, not individual Skill quality
    Compatibility0 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    Postpartum-genushyacinthus29/dotnet-skills
    Skill path
    skills/dotnet-wpf/SKILL.md
    Commit
    e520b1e9a27485d8b5f3ec0b71dfcd85ab371a40
    License
    MIT
    Collected
    2026-08-28
    Default branch
    main
    View the original SKILL.md

    WPF

    Trigger On

    • working on WPF UI, MVVM, binding, commands, or desktop modernization
    • migrating WPF from .NET Framework to .NET
    • integrating newer Windows capabilities into a WPF app
    • implementing data binding, styles, templates, or control customization

    Documentation

    References

    • patterns.md - MVVM patterns, binding patterns, command patterns, and reusable architectural approaches
    • anti-patterns.md - Common WPF mistakes and how to avoid them

    Workflow

    1. Confirm Windows-only scope — WPF is Windows-only even when the wider .NET stack is cross-platform
    2. Apply MVVM pattern — keep views dumb, logic in ViewModels, use commands
    3. Manage data binding explicitly — choose correct binding modes, validate at runtime
    4. Use styles and templates deliberately — keep UI composable, avoid page-specific hacks
    5. Handle threading correctly — use Dispatcher for UI updates, async/await for long operations
    6. Validate both designer and runtime — XAML composition failures often surface only at runtime

    Project Structure

    MyWpfApp/
    ├── MyWpfApp/
    │   ├── App.xaml                # Application entry
    │   ├── MainWindow.xaml         # Main window
    │   ├── Views/                  # XAML views/windows
    │   ├── ViewModels/             # MVVM ViewModels
    │   ├── Models/                 # Domain models
    │   ├── Services/               # Business logic
    │   ├── Converters/             # Value converters
    │   ├── Resources/              # Styles, templates, dictionaries
    │   └── Controls/               # Custom controls
    └── MyWpfApp.Tests/
    

    MVVM Pattern

    ViewModel with MVVM Toolkit

    public partial class CustomersViewModel : ObservableObject
    {
        private readonly ICustomerService _customerService;
    
        [ObservableProperty]
        private ObservableCollection<Customer> _customers = [];
    
        [ObservableProperty]
        [NotifyCanExecuteChangedFor(nameof(SaveCommand))]
        private Customer? _selectedCustomer;
    
        [ObservableProperty]
        [NotifyCanExecuteChangedFor(nameof(RefreshCommand))]
        private bool _isLoading;
    
        public CustomersViewModel(ICustomerService customerService)
        {
            _customerService = customerService;
        }
    
        [RelayCommand(CanExecute = nameof(CanRefresh))]
        private async Task RefreshAsync()
        {
            IsLoading = true;
            try
            {
                var items = await _customerService.GetAllAsync();
                Customers = new ObservableCollection<Customer>(items);
            }
            finally
            {
                IsLoading = false;
            }
        }
    
        private bool CanRefresh() => !IsLoading;
    
        [RelayCommand(CanExecute = nameof(CanSave))]
        private async Task SaveAsync()
        {
            if (SelectedCustomer is null) return;
            await _customerService.SaveAsync(SelectedCustomer);
        }
    
        private bool CanSave() => SelectedCustomer is not null;
    }
    

    View Binding

    <Window x:Class="MyWpfApp.Views.CustomersView"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:vm="clr-namespace:MyWpfApp.ViewModels"
            d:DataContext="{d:DesignInstance Type=vm:CustomersViewModel}">
    
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
    
            <ToolBar Grid.Row="0">
                <Button Content="Refresh"
                        Command="{Binding RefreshCommand}"/>
                <Button Content="Save"
                        Command="{Binding SaveCommand}"/>
            </ToolBar>
    
            <DataGrid Grid.Row="1"
                      ItemsSource="{Binding Customers}"
                      SelectedItem="{Binding SelectedCustomer}"
                      AutoGenerateColumns="False">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Name"
                                        Binding="{Binding Name}"/>
                    <DataGridTextColumn Header="Email"
                                        Binding="{Binding Email}"/>
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Window>
    

    Dependency Injection

    public partial class App : Application
    {
        private readonly IHost _host;
    
        public App()
        {
            _host = Host.CreateDefaultBuilder()
                .ConfigureServices((context, services) =>
                {
                    // Services
                    services.AddSingleton<ICustomerService, CustomerService>();
                    services.AddSingleton<INavigationService, NavigationService>();
    
                    // ViewModels
                    services.AddTransient<CustomersViewModel>();
                    services.AddTransient<CustomerDetailViewModel>();
    
                    // Views
                    services.AddTransient<MainWindow>();
                    services.AddTransient<CustomersView>();
                })
                .Build();
        }
    
        protected override async void OnStartup(StartupEventArgs e)
        {
            await _host.StartAsync();
            var mainWindow = _host.Services.GetRequiredService<MainWindow>();
            mainWindow.Show();
            base.OnStartup(e);
        }
    
        protected override async void OnExit(ExitEventArgs e)
        {
            await _host.StopAsync();
            _host.Dispose();
            base.OnExit(e);
        }
    }
    

    Data Binding Modes

    <!-- OneTime: Read once at initialization -->
    <TextBlock Text="{Binding CreatedDate, Mode=OneTime}"/>
    
    <!-- OneWay: Source to target only (default for most properties) -->
    <TextBlock Text="{Binding Name, Mode=OneWay}"/>
    
    <!-- TwoWay: Bidirectional synchronization -->
    <TextBox Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    
    <!-- OneWayToSource: Target to source only -->
    <TextBox Text="{Binding SearchFilter, Mode=OneWayToSource}"/>
    

    Value Converters

    public class BooleanToVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is bool boolValue)
            {
                return boolValue ? Visibility.Visible : Visibility.Collapsed;
            }
            return Visibility.Collapsed;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value is Visibility.Visible;
        }
    }
    
    // Multi-value converter
    public class MultiplyConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if (values.Length == 2 && values[0] is double a && values[1] is double b)
            {
                return a * b;
            }
            return 0.0;
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    Styles and Templates

    Resource Dictionary

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    
        <!-- Implicit style for all Buttons -->
        <Style TargetType="Button">
            <Setter Property="Padding" Value="10,5"/>
            <Setter Property="Margin" Value="5"/>
            <Setter Property="Background" Value="#0078D4"/>
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border Background="{TemplateBinding Background}"
                                CornerRadius="4"
                                Padding="{TemplateBinding Padding}">
                            <ContentPresenter HorizontalAlignment="Center"
                                              VerticalAlignment="Center"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    
        <!-- Named style -->
        <Style x:Key="DangerButton" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
            <Setter Property="Background" Value="#D32F2F"/>
        </Style>
    </ResourceDictionary>
    

    Threading and Dispatcher

    // Update UI from background thread
    await Task.Run(async () =>
    {
        var data = await LoadDataAsync();
    
        // Must use Dispatcher to update UI
        Application.Current.Dispatcher.Invoke(() =>
        {
            Items.Clear();
            foreach (var item in data)
            {
                Items.Add(item);
            }
        });
    });
    
    // Better: Use async/await properly
    private async Task LoadDataAsync()
    {
        IsLoading = true;
        try
        {
            // This runs on background thread
            var data = await _service.GetDataAsync();
    
            // This automatically marshals to UI thread
            Items = new ObservableCollection<Item>(data);
        }
        finally
        {
            IsLoading = false;
        }
    }
    

    Anti-Patterns to Avoid

    Anti-PatternWhy It's BadBetter Approach
    Logic in code-behindHard to test, tight couplingUse MVVM with ViewModels
    Synchronous blocking callsUI freezesUse async/await
    Manual INotifyPropertyChangedBoilerplate, error-proneUse MVVM Toolkit attributes
    Hardcoded colors/sizesInconsistent, hard to themeUse resource dictionaries
    Direct Dispatcher.Invoke everywhereComplex, error-pronePrefer async/await marshaling
    God ViewModelUnmaintainableSplit into focused ViewModels
    Skipping binding validationRuntime errors hiddenUse ValidatesOnDataErrors
    Event handlers for everythingMemory leaks, couplingUse commands and bindings

    Best Practices

    1. Use compiled bindings in .NET 5+:

      • Enable x:CompileBindings="True" for performance
    2. Implement INotifyDataErrorInfo for validation:

      [ObservableProperty]
      [NotifyDataErrorInfo]
      [Required(ErrorMessage = "Name is required")]
      [MinLength(2, ErrorMessage = "Name must be at least 2 characters")]
      private string _name = string.Empty;
      
    3. Use weak event patterns for long-lived subscriptions:

      WeakEventManager<Source, EventArgs>.AddHandler(source, "EventName", Handler);
      
    4. Virtualize large collections:

      <ListBox VirtualizingPanel.IsVirtualizing="True"
               VirtualizingPanel.VirtualizationMode="Recycling"
               ItemsSource="{Binding LargeCollection}"/>
      
    5. Freeze Freezables when possible:

      var brush = new SolidColorBrush(Colors.Blue);
      brush.Freeze(); // Thread-safe, better performance
      
    6. Use design-time data:

      <Window d:DataContext="{d:DesignInstance Type=vm:MainViewModel, IsDesignTimeCreatable=True}">
      

    Testing

    [Fact]
    public async Task RefreshCommand_LoadsCustomers()
    {
        var mockService = new Mock<ICustomerService>();
        mockService.Setup(s => s.GetAllAsync())
            .ReturnsAsync(new[] { new Customer { Name = "Test" } });
    
        var viewModel = new CustomersViewModel(mockService.Object);
    
        await viewModel.RefreshCommand.ExecuteAsync(null);
    
        Assert.Single(viewModel.Customers);
        Assert.Equal("Test", viewModel.Customers[0].Name);
    }
    
    [Fact]
    public void SaveCommand_CannotExecute_WhenNoSelection()
    {
        var mockService = new Mock<ICustomerService>();
        var viewModel = new CustomersViewModel(mockService.Object);
    
        viewModel.SelectedCustomer = null;
    
        Assert.False(viewModel.SaveCommand.CanExecute(null));
    }
    

    Deliver

    • cleaner WPF views and view-model boundaries
    • safer binding and threading behavior
    • migration guidance grounded in actual Windows constraints
    • MVVM pattern with testable ViewModels

    Validate

    • binding and command flows are explicit
    • code-behind is not carrying hidden business logic
    • Windows-only assumptions are acknowledged
    • threading and dispatcher usage is correct
    • styles and resources are properly organized

    Frequently asked questions

    What to verify before installation and use

    What does the dotnet-wpf source document cover?

    Build and modernize WPF applications on . NET with correct XAML, data binding, commands, threading, styling, and Windows desktop migration decisions.

    How do I install dotnet-wpf?

    The source record exposes this install command: npx skills add https://github.com/Postpartum-genushyacinthus29/dotnet-skills --skill "skills/dotnet-wpf". Inspect the command and pinned source before running it.

    Which permission-related actions were detected?

    Static rules flagged network in the source; the page lists the matching lines and excerpts.

    Alternatives

    Compare before choosing

    Computed 989

    Postpartum-genushyacinthus29/dotnet-skills

    dotnet-mvvm

    Implement the Model-View-ViewModel pattern in .NET applications with proper separation of concerns, data binding, commands, and testable ViewModels using MVVM Toolkit.

    Computed 976

    mgiovani/cc-arsenal

    team-review

    Multi-agent review team: architecture, security, performance, testing, style, docs/UX, plus an adversary that cross-examines the other 6, for security-sensitive, architectural, or large PRs (15+ files) where a single-agent pass risks missing cross-cutting issues. Use for auth/payments/PII changes, schema/pattern changes, compliance sign-off, or when asked to 'get the review team on this' / 'multi-agent review' / 'thorough review before merge'. For a standard PR or a quick pre-merge check, use /r

    Computed 965,277

    dotnet/skills

    dotnet-webapi

    Guides creation and modification of ASP.NET Core Web API endpoints with correct HTTP semantics, OpenAPI metadata, and error handling. USE FOR: adding new API endpoints (controllers or minimal APIs), wiring up OpenAPI/Swagger, creating .http test files, setting up global error handling middleware. DO NOT USE FOR: general C# coding style, EF Core data access or query optimization (use optimizing-ef-core-queries), frontend/Blazor work, gRPC services, or SignalR hubs.

    Computed 9660

    almanak-co/sdk

    almanak-strategy-builder

    Build, test, and deploy DeFi trading strategies using the Almanak SDK. ALWAYS use this skill when the user mentions almanak, DeFi strategy, trading strategy, yield farming, liquidity provision, token swap, borrowing, lending, perpetuals, staking, vault deposit, bridging tokens, backtesting, paper trading, or on-chain execution. Use for writing strategy.py files, composing intents (Swap, LP, Borrow, Supply, Perp, Bridge, Stake, Vault, Prediction), working with config.json strategy parameters, run