Back to Skills

implementing-wpf-adorners

verified

Implements WPF Adorner decoration layers with AdornerLayer, AdornerDecorator, and custom Adorner patterns. Use when building drag handles, validation indicators, watermarks, selection visuals, or resize grips.

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/implementing-wpf-adorners/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/implementing-wpf-adorners/SKILL.md -a claude-code --skill implementing-wpf-adorners

Installation paths:

Claude
.claude/skills/implementing-wpf-adorners/
Powered by add-skill CLI

Instructions

# WPF Adorner Patterns

Adorner is a mechanism for overlaying decorative visual elements on top of UIElements.

## 1. Adorner Concept

### 1.1 Characteristics

- **AdornerLayer**: Separate rendering layer that holds Adorners
- **Z-Order**: Always renders above the adorned element
- **Layout Independent**: No effect on target element's layout
- **Event Support**: Can receive mouse/keyboard events

### 1.2 Usage Scenarios

| Scenario | Description |
|----------|-------------|
| **Validation Display** | Input field error display |
| **Drag Handles** | Element move/resize handles |
| **Watermark** | Hint text for empty TextBox |
| **Selection Display** | Highlight selected elements |
| **Tooltip/Badge** | Additional info display on elements |
| **Drag and Drop** | Preview during drag |

---

## 2. Basic Adorner Implementation

### 2.1 Simple Adorner

```csharp
namespace MyApp.Adorners;

using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;

/// <summary>
/// Adorner that draws border around element
/// </summary>
public sealed class BorderAdorner : Adorner
{
    private readonly Pen _borderPen;

    public BorderAdorner(UIElement adornedElement) : base(adornedElement)
    {
        _borderPen = new Pen(Brushes.Red, 2)
        {
            DashStyle = DashStyles.Dash
        };
        _borderPen.Freeze();

        // Disable mouse events (decoration only)
        IsHitTestVisible = false;
    }

    protected override void OnRender(DrawingContext drawingContext)
    {
        var rect = new Rect(AdornedElement.RenderSize);

        // Draw border
        drawingContext.DrawRectangle(null, _borderPen, rect);
    }
}
```

### 2.2 Applying Adorner

```csharp
// Get AdornerLayer
var adornerLayer = AdornerLayer.GetAdornerLayer(targetElement);

if (adornerLayer is not null)
{
    // Add Adorner
    var adorner = new BorderAdorner(targetElement);
    adornerLayer.Add(adorner);
}
```

### 2.3 Removing Adorner

```csharp
// Remove all Adorners from s

Validation Details

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