What Are Markup Extensions
A markup extension is a XAML construct that lets an attribute value be computed at parse time rather than written as a literal string. Any class that derives from System.Windows.Markup.MarkupExtension and overrides ProvideValue can be invoked from XAML using curly-brace syntax, such as {Binding Path=Name} or {StaticResource AppBrush}, and the XAML parser calls ProvideValue to obtain the actual object that gets assigned to the property.
Cricket analogy: Think of a markup extension like a night-watchman batter sent in for the last over: the scorecard slot (the attribute) is fixed, but who actually fills it is decided at the last moment by the team management, just as ProvideValue decides the real value only when the parser reaches that line.
Curly-Brace Syntax and How the Parser Resolves It
The curly-brace syntax {ExtensionName Arg1, Property2=Value2} is parsed by the XamlReader into a call against the corresponding MarkupExtension subclass. Positional arguments map to constructor parameters in declaration order, while Name=Value pairs map to public settable properties on the extension instance. Extensions can be nested, for example {Binding Converter={StaticResource BoolToVisibilityConverter}}, where the inner extension is fully resolved before being passed as a property value to the outer one.
Cricket analogy: It is like reading a cricket team's playing XI where the first names are locked batting order (positional) but roles like 'wicketkeeper' or 'vice-captain' are assigned by name afterward, just as positional and named markup-extension arguments are resolved differently by the parser.
Built-in and Custom Markup Extensions
The XAML and WPF/UWP frameworks ship several built-in extensions including {Binding}, {StaticResource}, {DynamicResource}, {x:Static}, {x:Type}, {x:Null}, and {x:Array}. Beyond these, developers can author custom extensions by subclassing MarkupExtension and implementing ProvideValue(IServiceProvider serviceProvider); the IServiceProvider parameter exposes services such as IProvideValueTarget, which reveals the target object and property the extension is being applied to, enabling context-aware value production.
Cricket analogy: It is like a franchise's core squad of specialist players (built-in extensions) supplemented by a locally scouted talent (custom extension) who still has to prove themselves against the same selection criteria, just as a custom MarkupExtension must still honor the ProvideValue contract.
public class UppercaseExtension : MarkupExtension
{
public string Text { get; set; }
public UppercaseExtension() { }
public UppercaseExtension(string text)
{
Text = text;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return Text?.ToUpperInvariant() ?? string.Empty;
}
}
<!-- Usage in XAML -->
<TextBlock Text="{local:Uppercase 'hello world'}" />By convention, a custom markup extension class name ends in 'Extension', but XAML lets you drop that suffix when using the curly-brace syntax, so UppercaseExtension can be invoked simply as {local:Uppercase ...}.
- Markup extensions defer value creation to parse time via a ProvideValue method.
- Curly-brace syntax {Name Arg} maps positional arguments to constructor parameters and Name=Value pairs to properties.
- Extensions can be nested, with inner extensions resolving before outer ones consume their result.
- Built-in extensions include Binding, StaticResource, DynamicResource, x:Static, x:Type, x:Null, and x:Array.
- Custom extensions subclass MarkupExtension and override ProvideValue(IServiceProvider).
- IServiceProvider exposes IProvideValueTarget so a custom extension can inspect the target object/property.
- The 'Extension' suffix on a class name can be omitted when invoking it from XAML.
Practice what you learned
1. What method must a class override to function as a markup extension?
2. In {Binding Path=Name, Mode=TwoWay}, how are Path and Mode resolved by the parser?
3. Which interface, obtainable via IServiceProvider, lets a custom extension discover the target object and property it is applied to?
4. Which of these is NOT a built-in XAML markup extension?
5. What happens when a markup extension is nested inside another, such as {Binding Converter={StaticResource MyConverter}}?
Was this page helpful?
You May Also Like
The Binding Markup Extension
How {Binding} connects UI properties to data-source properties, including Path, Mode, and source-resolution options.
StaticResource and DynamicResource
The difference between resolving a resource once at parse time versus keeping a live, updating reference to it.
x:Static and x:Type
Bridging XAML to CLR code: pulling in static field/property values with x:Static and referencing types themselves with x:Type.
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 TechnologiesWPF (Windows Presentation Foundation) Study Notes
.NET · 30 topics
Microsoft TechnologiesMVVM Design Pattern Study Notes
.NET · 30 topics