Implements lightweight rendering using WPF DrawingVisual with ContainerVisual, VisualCollection, and DrawingContext. Use when rendering large-scale graphics, charts, game graphics, or custom visuals.
View on GitHubchristian289/dotnet-with-claudecode
wpf-dev-pack
January 23, 2026
Select agents to install to:
npx add-skill https://github.com/christian289/dotnet-with-claudecode/blob/main/wpf-dev-pack/skills/rendering-with-drawingvisual/SKILL.md -a claude-code --skill rendering-with-drawingvisualInstallation paths:
.claude/skills/rendering-with-drawingvisual/# WPF DrawingVisual Patterns
DrawingVisual is a lightweight visual element faster than Shape, suitable for large-scale rendering.
## 1. Visual Hierarchy
```
Visual (abstract)
├── UIElement
│ └── FrameworkElement
│ └── Shape (heavyweight, event support)
│
├── DrawingVisual ← Lightweight, no events, direct rendering
├── ContainerVisual ← Groups multiple Visuals
└── HostVisual ← Cross-thread Visual
```
---
## 2. DrawingVisual vs Shape
| Aspect | DrawingVisual | Shape |
|--------|--------------|-------|
| **Overhead** | Low | High |
| **Layout** | Non-participating | Participating |
| **Events** | Manual implementation | Built-in support |
| **Data binding** | Not available | Available |
| **Use case** | Large elements, performance critical | Interactive UI |
---
## 3. Basic DrawingVisual Host
### 3.1 FrameworkElement Host
```csharp
namespace MyApp.Controls;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
/// <summary>
/// Control that hosts DrawingVisual
/// </summary>
public sealed class DrawingVisualHost : FrameworkElement
{
private readonly List<Visual> _visuals = [];
protected override int VisualChildrenCount => _visuals.Count;
protected override Visual GetVisualChild(int index)
{
return _visuals[index];
}
/// <summary>
/// Add Visual
/// </summary>
public void AddVisual(Visual visual)
{
_visuals.Add(visual);
AddVisualChild(visual);
AddLogicalChild(visual);
}
/// <summary>
/// Remove Visual
/// </summary>
public void RemoveVisual(Visual visual)
{
_visuals.Remove(visual);
RemoveVisualChild(visual);
RemoveLogicalChild(visual);
}
/// <summary>
/// Remove all Visuals
/// </summary>
public void ClearVisuals()
{
foreach (var visual in _visuals)
{
RemoveVisualChild(visual);
RemoveLogicalChild(visual);
}