Back to Skills

developing-wpf-customcontrols

verified

Develops WPF CustomControls using Parts and States Model best practices. Use when creating templatable controls with TemplatePart, TemplateVisualState, OnApplyTemplate, or VisualStateManager.

View on GitHub

Marketplace

dotnet-claude-plugins

christian289/dotnet-with-claudecode

Plugin

wpf-dev-pack

development

Repository

christian289/dotnet-with-claudecode
5stars

wpf-dev-pack/skills/developing-wpf-customcontrols/SKILL.md

Last Verified

January 23, 2026

Install Skill

Select agents to install to:

Scope:
npx add-skill https://github.com/christian289/dotnet-with-claudecode/blob/main/wpf-dev-pack/skills/developing-wpf-customcontrols/SKILL.md -a claude-code --skill developing-wpf-customcontrols

Installation paths:

Claude
.claude/skills/developing-wpf-customcontrols/
Powered by add-skill CLI

Instructions

# WPF CustomControl Development - Parts and States Model

Workflow for developing WPF CustomControls with appearance customization capability.

## Development Flow

### 1. Control Inheritance Decision

```
UserControl Selection Criteria:
- Need rapid development
- ControlTemplate customization not required
- Complex theme support not required

Control Inheritance Selection Criteria:
- Need appearance customization via ControlTemplate
- Need various theme support
- Need same extensibility as WPF built-in controls
```

### 2. Define Control Contract

Declare `TemplatePart` and `TemplateVisualState` attributes on the class:

```csharp
[TemplatePart(Name = PartUpButton, Type = typeof(RepeatButton))]
[TemplatePart(Name = PartDownButton, Type = typeof(RepeatButton))]
[TemplateVisualState(Name = StatePositive, GroupName = GroupValueStates)]
[TemplateVisualState(Name = StateNegative, GroupName = GroupValueStates)]
[TemplateVisualState(Name = StateFocused, GroupName = GroupFocusStates)]
[TemplateVisualState(Name = StateUnfocused, GroupName = GroupFocusStates)]
public class NumericUpDown : Control
{
    // Define Part/State names as const
    private const string PartUpButton = "PART_UpButton";
    private const string PartDownButton = "PART_DownButton";
    private const string GroupValueStates = "ValueStates";
    private const string GroupFocusStates = "FocusStates";
    private const string StatePositive = "Positive";
    private const string StateNegative = "Negative";
    private const string StateFocused = "Focused";
    private const string StateUnfocused = "Unfocused";
}
```

### 3. Template Part Property Pattern

Wrap Part elements as private properties, subscribe/unsubscribe events in setter:

```csharp
private RepeatButton? _upButton;
private RepeatButton? UpButtonElement
{
    get => _upButton;
    set
    {
        // Unsubscribe from existing element's events
        if (_upButton is not null)
            _upButton.Click -= OnUpButtonClick;

        _upButton =

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
5408 chars