Restructuring a Control's Visual Tree
While a Style with Setters can adjust properties like Background or FontSize, a ControlTemplate replaces the entire visual tree a control renders — you can turn a CheckBox into a toggle-switch look, or a Button into a hexagonal shape, without touching a single line of the control's C# logic. Because WPF controls are lookless, ControlTemplate is where the actual rendering lives; the default templates for every built-in control are themselves just XAML, visible in the theme resource files, which is why 'restyle instead of subclass' is the idiomatic WPF approach for visual customization.
Cricket analogy: Rebuilding a stadium's stand layout (seating, roof, sightlines) while the game's laws stay identical is like a ControlTemplate reshaping a control's visuals while its click/behavior logic remains untouched.
TemplateBinding and Named Parts
Inside a ControlTemplate, TemplateBinding (or the more capable {Binding RelativeSource={RelativeSource TemplatedParent}}) wires template elements back to properties on the control instance being templated — so a Border's Background inside a Button's template can pull from the Button's own Background property set by the consumer. Certain controls expect specific named parts inside their template, marked with x:Name and referenced by TemplatePartAttribute on the control class (e.g. Slider expects a 'PART_Track', ScrollBar expects 'PART_Track' with Thumb children) — omitting a required part silently breaks that control's interactive behavior even though it compiles fine.
Cricket analogy: TemplateBinding is like a stadium's electronic scoreboard automatically pulling live figures from the official scorer's system — the display (template) always reflects whatever value the source (control property) currently holds.
Triggers Inside a ControlTemplate
A ControlTemplate typically includes Triggers or VisualStateManager groups to react to the control's own state changes — IsMouseOver, IsPressed, IsEnabled — since without them a templated Button would look static and unresponsive to interaction. A Trigger inside Template.Triggers is scoped to that template instance and can only set properties on elements within the same template (or via TargetName), which is a key difference from a Style's own Triggers collection that applies at the control level.
Cricket analogy: A stadium's crowd-noise system automatically ramping up when a wicket falls (IsPressed-like state) versus staying calm during a dot ball is like a ControlTemplate trigger reacting to the control's interaction state.
<Style TargetType="Button" x:Key="HexButtonStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Path x:Name="HexShape"
Data="M50,0 100,25 100,75 50,100 0,75 0,25 Z"
Fill="{TemplateBinding Background}"
Stretch="Fill"/>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{TemplateBinding Content}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="HexShape" Property="Fill" Value="OrangeRed"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="HexShape" Property="Fill" Value="DarkRed"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>ContentPresenter (for ContentControl-derived controls like Button) and ItemsPresenter (for ItemsControl-derived controls like ListBox) are the standard placeholder elements inside a ControlTemplate that tell WPF where to insert the control's actual Content or item panel. Forgetting them means the template renders your chrome but never shows the control's real content.
If a control class declares required template parts via [TemplatePart(Name = "PART_Track", Type = typeof(Track))] (as Slider does), omitting that named element from a custom ControlTemplate compiles without error but breaks the control's interactivity at runtime — always check a control's documentation for required PART_ names before fully replacing its template.
- ControlTemplate replaces a control's entire visual tree while its behavioral logic (in C#) stays unchanged.
- TemplateBinding (or TemplatedParent RelativeSource binding) wires template elements to the control instance's own properties.
- Some controls require specific named parts (PART_xxx) for their interactive logic to function correctly.
- ContentPresenter/ItemsPresenter mark where the control's actual content or items render inside the template.
- Triggers inside ControlTemplate.Triggers react to control state (IsMouseOver, IsPressed) and can target named elements via TargetName.
- 'Restyle, don't subclass' is the idiomatic WPF approach since all built-in controls are already lookless.
Practice what you learned
1. What is the key difference between a Style's Setters and a ControlTemplate?
2. What does TemplateBinding do inside a ControlTemplate?
3. What happens if a required named part like PART_Track is omitted from a custom Slider template?
4. Which element inside a ControlTemplate marks where a ContentControl's actual Content renders?
5. Where can Setters inside ControlTemplate.Triggers apply their values?
Was this page helpful?
You May Also Like
Styles in WPF
How Style resources centralize and reuse property Setters across controls, including implicit styles, BasedOn inheritance, and Style-level triggers.
Triggers and Visual States
Property triggers, data triggers, event triggers with animations, and the VisualStateManager system that governs how controls react to state changes.
Data Templates
How DataTemplate lets WPF turn plain view-model objects into rich, reusable visual trees — the backbone of MVVM-driven UIs.
Related Reading
Related Study Notes in Microsoft Technologies
Browse all study notesWindows 10 / UWP Development Study Notes
.NET · 30 topics
Microsoft TechnologiesWindows Batch Scripting Study Notes
Batch · 30 topics
Microsoft TechnologiesMFC (Microsoft Foundation Classes) Study Notes
C++ · 30 topics
Microsoft TechnologiesSilverlight Study Notes
.NET · 30 topics
Microsoft TechnologiesXAML Study Notes
.NET · 30 topics
Microsoft TechnologiesMVVM Design Pattern Study Notes
.NET · 30 topics