Dotnet Desktop WPF Advanced Netframeworkdesktop 4.8
Dotnet Desktop WPF Advanced Netframeworkdesktop 4.8
In This Section
WPF Architecture
XAML in WPF
Base Element Classes
Element Tree and Serialization
WPF Property System
Events in WPF
Input
Drag and Drop
Resources
Documents
Globalization and Localization
Layout
Types migrated from WPF to System.Xaml
Migration and Interoperability
Performance
Threading Model
Unmanaged WPF API Reference
WPF Architecture
Article • 02/06/2023
This topic provides a guided tour of the Windows Presentation Foundation (WPF) class
hierarchy. It covers most of the major subsystems of WPF, and describes how they
interact. It also details some of the choices made by the architects of WPF.
System.Object
The primary WPF programming model is exposed through managed code. Early in the
design phase of WPF there were a number of debates about where the line should be
drawn between the managed components of the system and the unmanaged ones. The
CLR provides a number of features that make development more productive and robust
(including memory management, error handling, common type system, etc.) but they
come at a cost.
The major components of WPF are illustrated in the figure below. The red sections of
the diagram (PresentationFramework, PresentationCore, and milcore) are the major
code portions of WPF. Of these, only one is an unmanaged component – milcore.
Milcore is written in unmanaged code in order to enable tight integration with DirectX.
All display in WPF is done through the DirectX engine, allowing for efficient hardware
and software rendering. WPF also required fine control over memory and execution. The
composition engine in milcore is extremely performance sensitive, and required giving
up many advantages of the CLR to gain performance.
Communication between the managed and unmanaged portions of WPF is discussed
later in this topic. The remainder of the managed programming model is described
below.
System.Threading.DispatcherObject
Most objects in WPF derive from DispatcherObject, which provides the basic constructs
for dealing with concurrency and threading. WPF is based on a messaging system
implemented by the dispatcher. This works much like the familiar Win32 message pump;
in fact, the WPF dispatcher uses User32 messages for performing cross thread calls.
There are really two core concepts to understand when discussing concurrency in WPF –
the dispatcher and thread affinity.
During the design phase of WPF, the goal was to move to a single thread of execution,
but a non-thread "affinitized" model. Thread affinity happens when a component uses
the identity of the executing thread to store some type of state. The most common form
of this is to use the thread local store (TLS) to store state. Thread affinity requires that
each logical thread of execution be owned by only one physical thread in the operating
system, which can become memory intensive. In the end, WPF’s threading model was
kept in sync with the existing User32 threading model of single threaded execution with
thread affinity. The primary reason for this was interoperability – systems like OLE 2.0,
the clipboard, and Internet Explorer all require single thread affinity (STA) execution.
Given that you have objects with STA threading, you need a way to communicate
between threads, and validate that you are on the correct thread. Herein lies the role of
the dispatcher. The dispatcher is a basic message dispatching system, with multiple
prioritized queues. Examples of messages include raw input notifications (mouse
moved), framework functions (layout), or user commands (execute this method). By
deriving from DispatcherObject, you create a CLR object that has STA behavior, and will
be given a pointer to a dispatcher at creation time.
System.Windows.DependencyObject
One of the primary architectural philosophies used in building WPF was a preference for
properties over methods or events. Properties are declarative and allow you to more
easily specify intent instead of action. This also supported a model driven, or data
driven, system for displaying user interface content. This philosophy had the intended
effect of creating more properties that you could bind to, in order to better control the
behavior of an application.
In order to have more of the system driven by properties, a richer property system than
what the CLR provides was needed. A simple example of this richness is change
notifications. In order to enable two way binding, you need both sides of the bind to
support change notification. In order to have behavior tied to property values, you need
to be notified when the property value changes. The Microsoft .NET Framework has an
interface, INotifyPropertyChange, which allows an object to publish change
notifications, however it is optional.
WPF provides a richer property system, derived from the DependencyObject type. The
property system is truly a "dependency" property system in that it tracks dependencies
between property expressions and automatically revalidates property values when
dependencies change. For example, if you have a property that inherits (like FontSize),
the system is automatically updated if the property changes on a parent of an element
that inherits the value.
The foundation of the WPF property system is the concept of a property expression. In
this first release of WPF, the property expression system is closed, and the expressions
are all provided as part of the framework. Expressions are why the property system
doesn’t have data binding, styling, or inheritance hard coded, but rather provided by
later layers within the framework.
The property system also provides for sparse storage of property values. Because
objects can have dozens (if not hundreds) of properties, and most of the values are in
their default state (inherited, set by styles, etc.), not every instance of an object needs to
have the full weight of every property defined on it.
The final new feature of the property system is the notion of attached properties. WPF
elements are built on the principle of composition and component reuse. It is often the
case that some containing element (like a Grid layout element) needs additional data on
child elements to control its behavior (like the Row/Column information). Instead of
associating all of these properties with every element, any object is allowed to provide
property definitions for any other object. This is similar to the "expando" features of
JavaScript.
System.Windows.Media.Visual
With a system defined, the next step is getting pixels drawn to the screen. The Visual
class provides for building a tree of visual objects, each optionally containing drawing
instructions and metadata about how to render those instructions (clipping,
transformation, etc.). Visual is designed to be extremely lightweight and flexible, so most
of the features have no public API exposure and rely heavily on protected callback
functions.
Visual is really the entry point to the WPF composition system. Visual is the point of
connection between these two subsystems, the managed API and the unmanaged
milcore.
WPF displays data by traversing the unmanaged data structures managed by the
milcore. These structures, called composition nodes, represent a hierarchical display tree
with rendering instructions at each node. This tree, illustrated on the right hand side of
the figure below, is only accessible through a messaging protocol.
When programming WPF, you create Visual elements, and derived types, which
internally communicate to the composition tree through this messaging protocol. Each
Visual in WPF may create one, none, or several composition nodes.
There is a very important architectural detail to notice here – the entire tree of visuals
and drawing instructions is cached. In graphics terms, WPF uses a retained rendering
system. This enables the system to repaint at high refresh rates without the composition
system blocking on callbacks to user code. This helps prevent the appearance of an
unresponsive application.
Another important detail that isn’t really noticeable in the diagram is how the system
actually performs composition.
In User32 and GDI, the system works on an immediate mode clipping system. When a
component needs to be rendered, the system establishes a clipping bounds outside of
which the component isn’t allowed to touch the pixels, and then the component is
asked to paint pixels in that box. This system works very well in memory constrained
systems because when something changes you only have to touch the affected
component – no two components ever contribute to the color of a single pixel.
WPF uses a "painter's algorithm" painting model. This means that instead of clipping
each component, each component is asked to render from the back to the front of the
display. This allows each component to paint over the previous component's display.
The advantage of this model is that you can have complex, partially transparent shapes.
With today’s modern graphics hardware, this model is relatively fast (which wasn’t the
case when User32/ GDI were created).
First, if you think about the retained mode graphic system, this is really moving away
from an imperative DrawLine/DrawLine type model, to a data oriented model – new
Line()/new Line(). This move to data driven rendering allows complex operations on the
drawing instructions to be expressed using properties. The types deriving from Drawing
are effectively the object model for rendering.
Second, if you evaluate the animation system, you'll see that it is almost completely
declarative. Instead of requiring a developer to compute the next location, or next color,
you can express animations as a set of properties on an animation object. These
animations can then express the intent of the developer or designer (move this button
from here to there in 5 seconds), and the system can determine the most efficient way
to accomplish that.
System.Windows.UIElement
UIElement defines core subsystems including Layout, Input, and Events.
Layout is a core concept in WPF. In many systems there is either a fixed set of layout
models (HTML supports three models for layout; flow, absolute, and tables) or no model
for layout (User32 really only supports absolute positioning). WPF started with the
assumption that developers and designers wanted a flexible, extensible layout model,
which could be driven by property values rather than imperative logic. At the UIElement
level, the basic contract for layout is introduced – a two phase model with Measure and
Arrange passes.
Measure allows a component to determine how much size it would like to take. This is a
separate phase from Arrange because there are many situations where a parent element
will ask a child to measure several times to determine its optimal position and size. The
fact that parent elements ask child elements to measure demonstrates another key
philosophy of WPF – size to content. All controls in WPF support the ability to size to the
natural size of their content. This makes localization much easier, and allows for dynamic
layout of elements as things resize. The Arrange phase allows a parent to position and
determine the final size of each child.
A lot of time is often spent talking about the output side of WPF – Visual and related
objects. However there is a tremendous amount of innovation on the input side as well.
Probably the most fundamental change in the input model for WPF is the consistent
model by which input events are routed through the system.
Input originates as a signal on a kernel mode device driver and gets routed to the
correct process and thread through an intricate process involving the Windows kernel
and User32. Once the User32 message corresponding to the input is routed to WPF, it is
converted into a WPF raw input message and sent to the dispatcher. WPF allows for raw
input events to be converted to multiple actual events, enabling features like
"MouseEnter" to be implemented at a low level of the system with guaranteed delivery.
Each input event is converted to at least two events – a "preview" event and the actual
event. All events in WPF have a notion of routing through the element tree. Events are
said to "bubble" if they traverse from a target up the tree to the root, and are said to
"tunnel" if they start at the root and traverse down to a target. Input preview events
tunnel, enabling any element in the tree an opportunity to filter or take action on the
event. The regular (non-preview) events then bubble from the target up to the root.
This split between the tunnel and bubble phase makes implementation of features like
keyboard accelerators work in a consistent fashion in a composite world. In User32 you
would implement keyboard accelerators by having a single global table containing all
the accelerators you wanted to support (Ctrl+N mapping to "New"). In the dispatcher
for your application you would call TranslateAccelerator which would sniff the input
messages in User32 and determine if any matched a registered accelerator. In WPF this
wouldn’t work because the system is fully "composable" – any element can handle and
use any keyboard accelerator. Having this two phase model for input allows
components to implement their own "TranslateAccelerator".
To take this one step further, UIElement also introduces the notion of
CommandBindings. The WPF command system allows developers to define functionality
in terms of a command end point – something that implements ICommand. Command
bindings enable an element to define a mapping between an input gesture (Ctrl+N) and
a command (New). Both the input gestures and command definitions are extensible, and
can be wired together at usage time. This makes it trivial, for example, to allow an end
user to customize the key bindings that they want to use within an application.
To this point in the topic, "core" features of WPF – features implemented in the
PresentationCore assembly, have been the focus. When building WPF, a clean
separation between foundational pieces (like the contract for layout with Measure and
Arrange) and framework pieces (like the implementation of a specific layout like Grid)
was the desired outcome. The goal was to provide an extensibility point low in the stack
that would allow external developers to create their own frameworks if needed.
System.Windows.FrameworkElement
FrameworkElement can be looked at in two different ways. It introduces a set of policies
and customizations on the subsystems introduced in lower layers of WPF. It also
introduces a set of new subsystems.
FrameworkElement also provides easier API exposure to many features found in the core
layers of WPF. For example, FrameworkElement provides direct access to animation
through the BeginStoryboard method. A Storyboard provides a way to script multiple
animations against a set of properties.
The two most critical things that FrameworkElement introduces are data binding and
styles.
The data binding subsystem in WPF should be relatively familiar to anyone that has used
Windows Forms or ASP.NET for creating an application user interface (UI). In each of
these systems, there is a simple way to express that you want one or more properties
from a given element to be bound to a piece of data. WPF has full support for property
binding, transformation, and list binding.
One of the most interesting features of data binding in WPF is the introduction of data
templates. Data templates allow you to declaratively specify how a piece of data should
be visualized. Instead of creating a custom user interface that can be bound to data, you
can instead turn the problem around and let the data determine the display that will be
created.
Styling is really a lightweight form of data binding. Using styling you can bind a set of
properties from a shared definition to one or more instances of an element. Styles get
applied to an element either by explicit reference (by setting the Style property) or
implicitly by associating a style with the CLR type of the element.
System.Windows.Controls.Control
Control’s most significant feature is templating. If you think about WPF’s composition
system as a retained mode rendering system, templating allows a control to describe its
rendering in a parameterized, declarative manner. A ControlTemplate is really nothing
more than a script to create a set of child elements, with bindings to properties offered
by the control.
This split between the data model (properties), interaction model (commands and
events), and display model (templates) enables complete customization of a control’s
look and behavior.
A common aspect of the data model of controls is the content model. If you look at a
control like Button, you will see that it has a property named "Content" of type Object.
In Windows Forms and ASP.NET, this property would typically be a string – however that
limits the type of content you can put in a button. Content for a button can either be a
simple string, a complex data object, or an entire element tree. In the case of a data
object, the data template is used to construct a display.
Summary
WPF is designed to allow you to create dynamic, data driven presentation systems. Every
part of the system is designed to create objects through property sets that drive
behavior. Data binding is a fundamental part of the system, and is integrated at every
layer.
Traditional applications create a display and then bind to some data. In WPF, everything
about the control, every aspect of the display, is generated by some type of data
binding. The text found inside a button is displayed by creating a composed control
inside of the button and binding its display to the button’s content property.
When you begin developing WPF based applications, it should feel very familiar. You can
set properties, use objects, and data bind in much the same way that you can using
Windows Forms or ASP.NET. With a deeper investigation into the architecture of WPF,
you'll find that the possibility exists for creating much richer applications that
fundamentally treat data as the core driver of the application.
See also
Visual
UIElement
ICommand
FrameworkElement
DispatcherObject
CommandBinding
Control
Data Binding Overview
Layout
Animation Overview
XAML in WPF
Article • 08/10/2023
In This Section
XAML in WPF
XAML Syntax In Detail
Code-Behind and XAML in WPF
XAML and Custom Classes for WPF
Markup Extensions and WPF XAML
XAML Namespaces and Namespace Mapping for WPF XAML
WPF XAML Namescopes
Inline Styles and Templates
White-space Processing in XAML
TypeConverters and XAML
XML Character Entities and XAML
XAML Namespace (x:) Language Features
WPF XAML Extensions
Markup Compatibility (mc:) Language Features
Related Sections
WPF Architecture
Base Elements
Element Tree and Serialization
Properties
Events
Input
Resources
Styling and Templating
Threading Model
XAML overview in WPF (.NET
Framework)
Article • 02/16/2023
This article describes the features of the XAML language and demonstrates how you can
use XAML to write Windows Presentation Foundation (WPF) apps. This article specifically
describes XAML as implemented by WPF. XAML itself is a larger language concept than
WPF.
What is XAML
XAML is a declarative markup language. As applied to the .NET Framework
programming model, XAML simplifies creating a UI for a .NET Framework app. You can
create visible UI elements in the declarative XAML markup, and then separate the UI
definition from the run-time logic by using code-behind files that are joined to the
markup through partial class definitions. XAML directly represents the instantiation of
objects in a specific set of backing types defined in assemblies. This is unlike most other
markup languages, which are typically an interpreted language without such a direct tie
to a backing type system. XAML enables a workflow where separate parties can work on
the UI and the logic of an app, using potentially different tools.
When represented as text, XAML files are XML files that generally have the .xaml
extension. The files can be encoded by any XML encoding, but encoding as UTF-8 is
typical.
The following example shows how you might create a button as part of a UI. This
example is intended to give you a flavor of how XAML represents common UI
programming metaphors (it is not a complete sample).
XAML
<StackPanel>
<Button Content="Click Me"/>
</StackPanel>
Much of the material in the next few sections will be elementary to you if you have
previous familiarity with the XML language. This is a consequence of one of the basic
design principles of XAML. The XAML language defines concepts of its own, but these
concepts work within the XML language and markup form.
Object element syntax always starts with an opening angle bracket ( < ). This is followed
by the name of the type where you want to create an instance. (The name can include a
prefix, a concept that will be explained later.) After this, you can optionally declare
attributes on the object element. To complete the object element tag, end with a closing
angle bracket ( > ). You can instead use a self-closing form that does not have any
content, by completing the tag with a forward slash and closing angle bracket in
succession ( /> ). For example, look at the previously shown markup snippet again.
XAML
<StackPanel>
<Button Content="Click Me"/>
</StackPanel>
This specifies two object elements: <StackPanel> (with content, and a closing tag later),
and <Button .../> (the self-closing form, with several attributes). The object elements
StackPanel and Button each map to the name of a class that is defined by WPF and is
part of the WPF assemblies. When you specify an object element tag, you create an
instruction for XAML processing to create a new instance of the underlying type. Each
instance is created by calling the parameterless constructor of the underlying type when
parsing and loading the XAML.
XAML
The syntax for the property element start tag is <TypeName.PropertyName> . Generally, the
content of that tag is an object element of the type that the property takes as its value.
After specifying the content, you must close the property element with an end tag. The
syntax for the end tag is </TypeName.PropertyName> .
If an attribute syntax is possible, using the attribute syntax is typically more convenient
and enables a more compact markup, but that is often just a matter of style, not a
technical limitation. The following example shows the same properties being set as in
the previous attribute syntax example, but this time by using property element syntax
for all properties of the Button .
XAML
<Button>
<Button.Background>
<SolidColorBrush Color="Blue"/>
</Button.Background>
<Button.Foreground>
<SolidColorBrush Color="Red"/>
</Button.Foreground>
<Button.Content>
This is a button
</Button.Content>
</Button>
Collection syntax
The XAML language includes some optimizations that produce more human-readable
markup. One such optimization is that if a particular property takes a collection type,
then items that you declare in markup as child elements within that property's value
become part of the collection. In this case a collection of child object elements is the
value being set to the collection property.
The following example shows collection syntax for setting values of the GradientStops
property.
XAML
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<!-- no explicit new GradientStopCollection, parser knows how to find or
create -->
<GradientStop Offset="0.0" Color="Red" />
<GradientStop Offset="1.0" Color="Blue" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
For example, Border specifies a content property of Child. The following two Border
elements are treated identically. The first one takes advantage of the content property
syntax and omits the Border.Child property element. The second one shows
Border.Child explicitly.
XAML
<Border>
<TextBox Width="300"/>
</Border>
<!--explicit equivalent-->
<Border>
<Border.Child>
<TextBox Width="300"/>
</Border.Child>
</Border>
As a rule of the XAML language, the value of a XAML content property must be given
either entirely before or entirely after any other property elements on that object
element. For instance, the following markup does not compile.
XAML
<Button>I am a
<Button.Background>Blue</Button.Background>
blue button</Button>
For more information about the specifics of XAML syntax, see XAML Syntax In Detail.
Text content
A small number of XAML elements can directly process text as their content. To enable
this, one of the following cases must be true:
The class must declare a content property, and that content property must be of a
type assignable to a string (the type could be Object). For instance, any
ContentControl uses Content as its content property and it is type Object, and this
supports the following usage on a ContentControl such as a Button:
<Button>Hello</Button> .
The type must declare a type converter, in which case the text content is used as
initialization text for that type converter. For example, <Brush>Blue</Brush>
converts the content value of Blue into a brush. This case is less common in
practice.
XAML
<StackPanel>
<Button>First Button</Button>
<Button>Second Button</Button>
</StackPanel>
Here, each Button is a child element of StackPanel. This is a streamlined and intuitive
markup that omits two tags for two different reasons.
Omitted StackPanel.Children property element: StackPanel derives from Panel.
Panel defines Panel.Children as its XAML content property.
XAML
<StackPanel>
<StackPanel.Children>
<!--<UIElementCollection>-->
<Button>First Button</Button>
<Button>Second Button</Button>
<!--</UIElementCollection>-->
</StackPanel.Children>
</StackPanel>
XAML
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ExampleNamespace.ExamplePage">
<Button Click="Button_Click" >Click Me!</Button>
</Page>
There is more to events and XAML in WPF than just this example of the attribute syntax.
For example, you might wonder what the ClickHandler referenced here represents and
how it is defined. This will be explained in the upcoming Events and XAML code-behind
section of this article.
Case and white space in XAML
In general, XAML is case-sensitive. For purposes of resolving backing types, WPF XAML
is case-sensitive by the same rules that the CLR is case-sensitive. Object elements,
property elements, and attribute names must all be specified by using the sensitive
casing when compared by name to the underlying type in the assembly, or to a member
of a type. XAML language keywords and primitives are also case-sensitive. Values are
not always case-sensitive. Case sensitivity for values will depend on the type converter
behavior associated with the property that takes the value, or the property value type.
For example, properties that take the Boolean type can take either true or True as
equivalent values, but only because the native WPF XAML parser type conversion for
string to Boolean already permits these as equivalents.
WPF XAML processors and serializers will ignore or drop all nonsignificant white space,
and will normalize any significant white space. This is consistent with the default white-
space behavior recommendations of the XAML specification. This behavior is only of
consequence when you specify strings within XAML content properties. In simplest
terms, XAML converts space, linefeed, and tab characters into spaces, and then
preserves one space if found at either end of a contiguous string. The full explanation of
XAML white-space handling is not covered in this article. For more information, see
White space processing in XAML.
Markup extensions
Markup extensions are a XAML language concept. When used to provide the value of an
attribute syntax, curly braces ( { and } ) indicate a markup extension usage. This usage
directs the XAML processing to escape from the general treatment of attribute values as
either a literal string or a string-convertible value.
The most common markup extensions used in WPF app programming are Binding, used
for data binding expressions, and the resource references StaticResource and
DynamicResource. By using markup extensions, you can use attribute syntax to provide
values for properties even if that property does not support an attribute syntax in
general. Markup extensions often use intermediate expression types to enable features
such as deferring values or referencing other objects that are only present at run-time.
For example, the following markup sets the value of the Style property using attribute
syntax. The Style property takes an instance of the Style class, which by default could not
be instantiated by an attribute syntax string. But in this case, the attribute references a
particular markup extension, StaticResource . When that markup extension is processed,
it returns a reference to a style that was previously instantiated as a keyed resource in a
resource dictionary.
XAML
<Page.Resources>
<SolidColorBrush x:Key="MyBrush" Color="Gold"/>
<Style TargetType="Border" x:Key="PageBackground">
<Setter Property="Background" Value="Blue"/>
</Style>
XAML
</Page.Resources>
<StackPanel>
<Border Style="{StaticResource PageBackground}">
XAML
</Border>
</StackPanel>
For a reference listing of all markup extensions for XAML implemented specifically in
WPF, see WPF XAML Extensions. For a reference listing of the markup extensions that
are defined by System.Xaml and are more widely available for .NET Framework XAML
implementations, see XAML Namespace (x:) Language Features. For more information
about markup extension concepts, see Markup Extensions and WPF XAML.
Type converters
In the XAML Syntax in Brief section, it was stated that the attribute value must be able to
be set by a string. The basic, native handling of how strings are converted into other
object types or primitive values is based on the String type itself, in addition to native
processing for certain types such as DateTime or Uri. But many WPF types or members
of those types extend the basic string attribute processing behavior in such a way that
instances of more complex object types can be specified as strings and attributes.
The Thickness structure is an example of a type that has a type conversion enabled for
XAML usages. Thickness indicates measurements within a nested rectangle and is used
as the value for properties such as Margin. By placing a type converter on Thickness, all
properties that use a Thickness are easier to specify in XAML because they can be
specified as attributes. The following example uses a type conversion and attribute
syntax to provide a value for a Margin:
XAML
The previous attribute syntax example is equivalent to the following more verbose
syntax example, where the Margin is instead set through property element syntax
containing a Thickness object element. The four key properties of Thickness are set as
attributes on the new instance:
XAML
7 Note
There are also a limited number of objects where the type conversion is the only
public way to set a property to that type without involving a subclass, because the
type itself does not have a parameterless constructor. An example is Cursor.
XAML
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
XAML
</Page>
The root element also contains the attributes xmlns and xmlns:x . These attributes
indicate to a XAML processor which XAML namespaces contain the type definitions for
backing types that the markup will reference as elements. The xmlns attribute
specifically indicates the default XAML namespace. Within the default XAML namespace,
object elements in the markup can be specified without a prefix. For most WPF app
scenarios, and for almost all of the examples given in the WPF sections of the SDK, the
default XAML namespace is mapped to the WPF namespace
http://schemas.microsoft.com/winfx/2006/xaml/presentation . The xmlns:x attribute
indicates an additional XAML namespace, which maps the XAML language namespace
http://schemas.microsoft.com/winfx/2006/xaml .
This usage of xmlns to define a scope for usage and mapping of a namescope is
consistent with the XML 1.0 specification. XAML namescopes are different from XML
namescopes only in that a XAML namescope also implies something about how the
namescope's elements are backed by types when it comes to type resolution and
parsing the XAML.
The xmlns attributes are only strictly necessary on the root element of each XAML file.
xmlns definitions will apply to all descendant elements of the root element (this
behavior is again consistent with the XML 1.0 specification for xmlns .) xmlns attributes
are also permitted on other elements underneath the root, and would apply to any
descendant elements of the defining element. However, frequent definition or
redefinition of XAML namespaces can result in a XAML markup style that is difficult to
read.
The WPF implementation of its XAML processor includes an infrastructure that has
awareness of the WPF core assemblies. The WPF core assemblies are known to contain
the types that support the WPF mappings to the default XAML namespace. This is
enabled through configuration that is part of your project build file and the WPF build
and project systems. Therefore, declaring the default XAML namespace as the default
xmlns is all that is necessary in order to reference XAML elements that come from WPF
assemblies.
The x: prefix
In the previous root element example, the prefix x: was used to map the XAML
namespace http://schemas.microsoft.com/winfx/2006/xaml , which is the dedicated
XAML namespace that supports XAML language constructs. This x: prefix is used for
mapping this XAML namespace in the templates for projects, in examples, and in
documentation throughout this SDK. The XAML namespace for the XAML language
contains several programming constructs that you will use frequently in your XAML. The
following is a listing of the most common x: prefix programming constructs you will
use:
x:Key: Sets a unique key for each resource in a ResourceDictionary (or similar
dictionary concepts in other frameworks). x:Key will probably account for 90
percent of the x: usages you will see in a typical WPF app's markup.
x:Class: Specifies the CLR namespace and class name for the class that provides
code-behind for a XAML page. You must have such a class to support code-behind
per the WPF programming model, and therefore you almost always see x:
mapped, even if there are no resources.
x:Name: Specifies a run-time object name for the instance that exists in run-time
code after an object element is processed. In general, you will frequently use a
WPF-defined equivalent property for x:Name. Such properties map specifically to a
CLR backing property and are thus more convenient for app programming, where
you frequently use run-time code to find the named elements from initialized
XAML. The most common such property is FrameworkElement.Name. You might
still use x:Name when the equivalent WPF framework-level Name property is not
supported in a particular type. This occurs in certain animation scenarios.
x:Static: Enables a reference that returns a static value that is not otherwise a
XAML-compatible property.
x:Type: Constructs a Type reference based on a type name. This is used to specify
attributes that take Type, such as Style.TargetType, although frequently the
property has native string-to-Type conversion in such a way that the x:Type
markup extension usage is optional.
XAML
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:custom="clr-
namespace:NumericUpDownCustomControl;assembly=CustomLibrary"
>
<StackPanel Name="LayoutRoot">
<custom:NumericUpDown Name="numericCtrl1" Width="100" Height="60"/>
...
</StackPanel>
</Page>
For more information about custom types in XAML, see XAML and Custom Classes for
WPF.
For more information about how XML namespaces and code namespaces in assemblies
are related, see XAML Namespaces and Namespace Mapping for WPF XAML.
In the examples so far, you have seen several buttons, but none of these buttons had
any logical behavior associated with them yet. The primary application-level mechanism
for adding a behavior for an object element is to use an existing event of the element
class, and to write a specific handler for that event that is invoked when that event is
raised at run-time. The event name and the name of the handler to use are specified in
the markup, whereas the code that implements your handler is defined in the code-
behind.
XAML
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ExampleNamespace.ExamplePage">
<Button Click="Button_Click" >Click Me!</Button>
</Page>
C#
namespace ExampleNamespace
{
public partial class ExamplePage
{
void Button_Click(object sender, RoutedEventArgs e)
{
Button b = e.Source as Button;
b.Foreground = Brushes.Red;
}
}
}
Notice that the code-behind file uses the CLR namespace ExampleNamespace and
declares ExamplePage as a partial class within that namespace. This parallels the x:Class
attribute value of ExampleNamespace . ExamplePage that was provided in the markup root.
The WPF markup compiler will create a partial class for any compiled XAML file, by
deriving a class from the root element type. When you provide code-behind that also
defines the same partial class, the resulting code is combined within the same
namespace and class of the compiled app.
For more information about requirements for code-behind programming in WPF, see
Code-behind, Event Handler, and Partial Class Requirements in WPF.
If you do not want to create a separate code-behind file, you can also inline your code
in a XAML file. However, inline code is a less versatile technique that has substantial
limitations. For more informaiton, see Code-Behind and XAML in WPF.
Routed events
A particular event feature that is fundamental to WPF is a routed event. Routed events
enable an element to handle an event that was raised by a different element, as long as
the elements are connected through a tree relationship. When specifying event handling
with a XAML attribute, the routed event can be listened for and handled on any element,
including elements that do not list that particular event in the class members table. This
is accomplished by qualifying the event name attribute with the owning class name. For
instance, the parent StackPanel in the ongoing StackPanel / Button example could
register a handler for the child element button's Click event by specifying the attribute
Button.Click on the StackPanel object element, with your handler name as the
attribute value. For more information, see Routed Events Overview.
The following example sets Name on a StackPanel element. Then, a handler on a Button
within that StackPanel references the StackPanel through its instance reference
buttonContainer as set by Name.
XAML
<StackPanel Name="buttonContainer">
XAML
C#
Just like a variable, the XAML name for an instance is governed by a concept of scope,
so that names can be enforced to be unique within a certain scope that is predictable.
The primary markup that defines a page denotes one unique XAML namescope, with
the XAML namescope boundary being the root element of that page. However, other
markup sources can interact with a page at run-time, such as styles or templates within
styles, and such markup sources often have their own XAML namescopes that do not
necessarily connect with the XAML namescope of the page. For more information on
x:Name and XAML namescopes, see Name, x:Name Directive, or WPF XAML
Namescopes.
Attached properties in XAML are typically used through attribute syntax. In attribute
syntax, you specify an attached property in the form ownerType.propertyName .
Superficially, this resembles a property element usage, but in this case the ownerType
you specify is always a different type than the object element where the attached
property is being set. ownerType is the type that provides the accessor methods that are
required by a XAML processor in order to get or set the attached property value.
The most common scenario for attached properties is to enable child elements to report
a property value to their parent element.
The following example illustrates the DockPanel.Dock attached property. The DockPanel
class defines the accessors for DockPanel.Dock and therefore owns the attached
property. The DockPanel class also includes logic that iterates its child elements and
specifically checks each element for a set value of DockPanel.Dock. If a value is found,
that value is used during layout to position the child elements. Use of the
DockPanel.Dock attached property and this positioning capability is in fact the
motivating scenario for the DockPanel class.
XAML
<DockPanel>
<Button DockPanel.Dock="Left" Width="100" Height="20">I am on the
left</Button>
<Button DockPanel.Dock="Right" Width="100" Height="20">I am on the
right</Button>
</DockPanel>
In WPF, most or all the attached properties are also implemented as dependency
properties. For more information, see Attached Properties Overview.
Attached events use a similar ownerType.eventName form of attribute syntax. Just like the
non-attached events, the attribute value for an attached event in XAML specifies the
name of the handler method that is invoked when the event is handled on the element.
Attached event usages in WPF XAML are less common. For more information, see
Attached Events Overview.
XAML security
XAML is a markup language that directly represents object instantiation and execution.
Therefore, elements created in XAML have the same ability to interact with system
resources (network access, file system IO, for example) as the equivalent generated code
does. XAML loaded in to a fully trusted app has the same access to the system resources
as the hosting app does.
This topic defines the terms that are used to describe the elements of XAML syntax.
These terms are used frequently throughout the remainder of this documentation, both
for WPF documentation specifically and for the other frameworks that use XAML or the
basic XAML concepts enabled by the XAML language support at the System.Xaml level.
This topic expands on the basic terminology introduced in the topic XAML in WPF.
For more information about the XAML language specification, download [MS-XAML]
from the Microsoft Download Center.
Properties and events as they appear as XAML members of a WPF type are often
inherited from base types. For example, consider this example: <Button
Background="Blue" .../> . The Background property is not an immediately declared
property on the Button class, if you were to look at the class definition, reflection results,
or the documentation. Instead, Background is inherited from the base Control class.
The class inheritance behavior of WPF XAML elements is a significant departure from a
schema-enforced interpretation of XML markup. Class inheritance can become complex,
particularly when intermediate base classes are abstract, or when interfaces are involved.
This is one reason that the set of XAML elements and their permissible attributes is
difficult to represent accurately and completely using the schema types that are typically
used for XML programming, such as DTD or XSD format. Another reason is that
extensibility and type-mapping features of the XAML language itself preclude
completeness of any fixed representation of the permissible types and members.
The element and tag must be closed by a forward slash (/) followed immediately
by a right angle bracket (>).
The opening tag must be completed by a right angle bracket (>). Other object
elements, property elements, or inner text, can follow the opening tag. Exactly
what content may be contained here is typically constrained by the object model
of the element. The equivalent closing tag for the object element must also exist,
in proper nesting and balance with other opening and closing tag pairs.
XAML as implemented by .NET has a set of rules that map object elements into types,
attributes into properties or events, and XAML namespaces to CLR namespaces plus
assembly. For WPF and .NET, XAML object elements map to .NET types as defined in
referenced assemblies, and the attributes map to members of those types. When you
reference a CLR type in XAML, you have access to the inherited members of that type as
well.
For example, the following example is object element syntax that instantiates a new
instance of the Button class, and also specifies a Name attribute and a value for that
attribute:
XAML
<Button Name="CheckoutButton"/>
The following example is object element syntax that also includes XAML content
property syntax. The inner text contained within will be used to set the TextBox XAML
content property, Text.
XAML
Content Models
A class might support a usage as a XAML object element in terms of the syntax, but that
element will only function properly in an application or page when it is placed in an
expected position of an overall content model or element tree. For example, a
MenuItem should typically only be placed as a child of a MenuBase derived class such as
Menu. Content models for specific elements are documented as part of the remarks on
the class pages for controls and other WPF classes that can be used as XAML elements.
You can use alternating quotes to place a literal quotation mark within an attribute.
For instance you can use single quotes as a means to declare a string that contains
a double quote character within it. Whether you use single or double quotes, you
should use a matching pair for opening and closing the attribute value string. There
are also escape sequences or other techniques available for working around
character restrictions imposed by any particular XAML syntax. See XML Character
Entities and XAML.
In order to be set through attribute syntax, a property must be public and must be
writeable. The value of the property in the backing type system must be a value type, or
must be a reference type that can be instantiated or referenced by a XAML processor
when accessing the relevant backing type.
For WPF XAML events, the event that is referenced as the attribute name must be public
and have a public delegate.
The property or event must be a member of the class or structure that is instantiated by
the containing object element.
The attribute value is filled by one of the following, using this processing order:
1. If the XAML processor encounters a curly brace, or an object element that derives
from MarkupExtension, then the referenced markup extension is evaluated first
rather than processing the value as a string, and the object returned by the markup
extension is used as the value. In many cases the object returned by a markup
extension will be a reference to an existing object, or an expression that defers
evaluation until run time, and is not a newly instantiated object.
Enumerations in XAML are processed intrinsically by XAML parsers, and the members of
an enumeration should be specified by specifying the string name of one of the
enumeration's named constants.
For nonflag enumeration values, the native behavior is to process the string of an
attribute value and resolve it to one of the enumeration values. You do not specify the
enumeration in the format Enumeration.Value, as you do in code. Instead, you specify
only Value, and Enumeration is inferred by the type of the property you are setting. If
you specify an attribute in the Enumeration.Value form, it will not resolve correctly.
For flagwise enumerations, the behavior is based on the Enum.Parse method. You can
specify multiple values for a flagwise enumeration by separating each value with a
comma. However, you cannot combine enumeration values that are not flagwise. For
instance, you cannot use the comma syntax to attempt to create a Trigger that acts on
multiple conditions of a nonflag enumeration:
XAML
Flagwise enumerations that support attributes that are settable in XAML are rare in WPF.
However, one such enumeration is StyleSimulations. You could, for instance, use the
comma-delimited flagwise attribute syntax to modify the example provided in the
Remarks for the Glyphs class; StyleSimulations = "BoldSimulation" could become
StyleSimulations = "BoldSimulation,ItalicSimulation" . KeyBinding.Modifiers is
another property where more than one enumeration value can be specified. However,
this property happens to be a special case, because the ModifierKeys enumeration
supports its own type converter. The type converter for modifiers uses a plus sign (+) as
a delimiter rather than a comma (,). This conversion supports the more traditional syntax
to represent key combinations in Microsoft Windows programming, such as "Ctrl+Alt".
Properties and Event Member Name References
When specifying an attribute, you can reference any property or event that exists as a
member of the CLR type you instantiated for the containing object element.
Or, you can reference an attached property or attached event, independent of the
containing object element. (Attached properties are discussed in an upcoming section.)
You can also name any event from any object that is accessible through the default
namespace by using a typeName.event partially qualified name; this syntax supports
attaching handlers for routed events where the handler is intended to handle events
routing from child elements, but the parent element does not also have that event in its
members table. This syntax resembles an attached event syntax, but the event here is
not a true attached event. Instead, you are referencing an event with a qualified name.
For more information, see Routed Events Overview.
For some scenarios, property names are sometimes provided as the value of an
attribute, rather than the attribute name. That property name can also include qualifiers,
such as the property specified in the form ownerType.dependencyPropertyName. This
scenario is common when writing styles or templates in XAML. The processing rules for
property names provided as an attribute value are different, and are governed by the
type of the property being set or by the behaviors of particular WPF subsystems. For
details, see Styling and Templating.
Another usage for property names is when an attribute value describes a property-
property relationship. This feature is used for data binding and for storyboard targets,
and is enabled by the PropertyPath class and its type converter. For a more complete
description of the lookup semantics, see PropertyPath XAML Syntax.
Specifically, the syntax begins with a left angle bracket (<), followed immediately by the
type name of the class or structure that the property element syntax is contained within.
This is followed immediately by a single dot (.), then by the name of a property, then by
a right angle bracket (>). As with attribute syntax, that property must exist within the
declared public members of the specified type. The value to be assigned to the property
is contained within the property element. Typically, the value is given as one or more
object elements, because specifying objects as values is the scenario that property
element syntax is intended to address. Finally, an equivalent closing tag specifying the
same elementTypeName.propertyName combination must be provided, in proper
nesting and balance with other element tags.
For example, the following is property element syntax for the ContextMenu property of
a Button.
XAML
<Button>
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="1">First item</MenuItem>
<MenuItem Header="2">Second item</MenuItem>
</ContextMenu>
</Button.ContextMenu>
Right-click me!</Button>
The value within a property element can also be given as inner text, in cases where the
property type being specified is a primitive value type, such as String, or an enumeration
where a name is specified. These two usages are somewhat uncommon, because each of
these cases could also use a simpler attribute syntax. One scenario for filling a property
element with a string is for properties that are not the XAML content property but still
are used for representation of UI text, and particular white-space elements such as
linefeeds are required to appear in that UI text. Attribute syntax cannot preserve
linefeeds, but property element syntax can, so long as significant white-space
preservation is active (for details, see White space processing in XAML). Another
scenario is so that x:Uid Directive can be applied to the property element and thus mark
the value within as a value that should be localized in the WPF output BAML or by other
techniques.
A property element is not represented in the WPF logical tree. A property element is just
a particular syntax for setting a property, and is not an element that has an instance or
object backing it. (For details on the logical tree concept, see Trees in WPF.)
For properties where both attribute and property element syntax are supported, the two
syntaxes generally have the same result, although subtleties such as white-space
handling can vary slightly between syntaxes.
Collection Syntax
The XAML specification requires XAML processor implementations to identify properties
where the value type is a collection. The general XAML processor implementation in
.NET is based on managed code and the CLR, and it identifies collection types through
one of the following:
Type derives from Array (for more information about arrays in XAML, see x:Array
Markup Extension.)
If the type of a property is a collection, then the inferred collection type does not need
to be specified in the markup as an object element. Instead, the elements that are
intended to become the items in the collection are specified as one or more child
elements of the property element. Each such item is evaluated to an object during
loading and added to the collection by calling the Add method of the implied collection.
For example, the Triggers property of Style takes the specialized collection type
TriggerCollection, which implements IList. It is not necessary to instantiate a
TriggerCollection object element in the markup. Instead, you specify one or more
Trigger items as elements within the Style.Triggers property element, where Trigger (or
a derived class) is the type expected as the item type for the strongly typed and implicit
TriggerCollection.
XAML
A property may be both a collection type and the XAML content property for that type
and derived types, which is discussed in the next section of this topic.
An implicit collection element creates a member in the logical tree representation, even
though it does not appear in the markup as an element. Usually the constructor of the
parent type performs the instantiation for the collection that is one of its properties, and
the initially empty collection becomes part of the object tree.
7 Note
In the .NET Reference pages for collection types, this syntax with the deliberate omission
of the object element for a collection is occasionally noted in the XAML syntax sections
as Implicit Collection Syntax.
With the exception of the root element, every object element in a XAML file that is
nested as a child element of another element is really an element that is one or both of
the following cases: a member of an implicit collection property of its parent element, or
an element that specifies the value of the XAML content property for the parent element
(XAML content properties will be discussed in an upcoming section). In other words, the
relationship of parent elements and child elements in a markup page is really a single
object at the root, and every object element beneath the root is either a single instance
that provides a property value of the parent, or one of the items within a collection that
is also a collection-type property value of the parent. This single-root concept is
common with XML, and is frequently reinforced in the behavior of APIs that load XAML
such as Load.
The following example is a syntax with the object element for a collection
(GradientStopCollection) specified explicitly.
XAML
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Offset="0.0" Color="Red" />
<GradientStop Offset="1.0" Color="Blue" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
Note that it is not always possible to explicitly declare the collection. For instance,
attempting to declare TriggerCollection explicitly in the previously shown Triggers
example would fail. Explicitly declaring the collection requires that the collection class
must support a parameterless constructor, and TriggerCollection does not have a
parameterless constructor.
XAML
<Button>I am a
<Button.Background>Blue</Button.Background>
blue button</Button>
This is illegal essentially because if this syntax were made explicit by using property
element syntax for the content property, then the content property would be set twice:
XAML
<Button>
<Button.Content>I am a </Button.Content>
<Button.Background>Blue</Button.Background>
<Button.Content> blue button</Button.Content>
</Button>
A similarly illegal example is if the content property is a collection, and child elements
are interspersed with property elements:
XAML
<StackPanel>
<Button>This example</Button>
<StackPanel.Resources>
<SolidColorBrush x:Key="BlueBrush" Color="Blue"/>
</StackPanel.Resources>
<Button>... is illegal XAML</Button>
</StackPanel>
XAML
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<StackPanel>
<Button>Button 1</Button>
<Button>Button 2</Button>
<Button>Button 3</Button>
</StackPanel>
</Page>
Note that neither the property element for Children nor the element for the
UIElementCollection is required in the markup. This is a design feature of XAML so that
recursively contained elements that define a UI are more intuitively represented as a tree
of nested elements with immediate parent-child element relationships, without
intervening property element tags or collection objects. In fact, UIElementCollection
cannot be specified explicitly in markup as an object element, by design. Because its
only intended use is as an implicit collection, UIElementCollection does not expose a
public parameterless constructor and thus cannot be instantiated as an object element.
You can have a child object element as the first immediate markup within an object
element. Then you can introduce property elements. Or, you can specify one or more
property elements, then content, then more property elements. But once a property
element follows content, you cannot introduce any further content, you can only add
property elements.
This content / property element order requirement does not apply to inner text used as
content. However, it is still a good markup style to keep inner text contiguous, because
significant white space will be difficult to detect visually in the markup if property
elements are interspersed with inner text.
XAML Namespaces
None of the preceding syntax examples specified a XAML namespace other than the
default XAML namespace. In typical WPF applications, the default XAML namespace is
specified to be the WPF namespace. You can specify XAML namespaces other than the
default XAML namespace and still use similar syntax. But then, anywhere where a class is
named that is not accessible within the default XAML namespace, that class name must
be preceded with the prefix of the XAML namespace as mapped to the corresponding
CLR namespace. For example, <custom:Example/> is object element syntax to instantiate
an instance of the Example class, where the CLR namespace containing that class (and
possibly the external assembly information that contains backing types) was previously
mapped to the custom prefix.
For more information about XAML namespaces, see XAML Namespaces and Namespace
Mapping for WPF XAML.
Markup Extensions
XAML defines a markup extension programming entity that enables an escape from the
normal XAML processor handling of string attribute values or object elements, and
defers the processing to a backing class. The character that identifies a markup
extension to a XAML processor when using attribute syntax is the opening curly brace
({), followed by any character other than a closing curly brace (}). The first string
following the opening curly brace must reference the class that provides the particular
extension behavior, where the reference may omit the substring "Extension" if that
substring is part of the true class name. Thereafter, a single space may appear, and then
each succeeding character is used as input by the extension implementation, up until
the closing curly brace is encountered.
The .NET XAML implementation uses the MarkupExtension abstract class as the basis for
all of the markup extensions supported by WPF as well as other frameworks or
technologies. The markup extensions that WPF specifically implements are often
intended to provide a means to reference other existing objects, or to make deferred
references to objects that will be evaluated at run time. For example, a simple WPF data
binding is accomplished by specifying the {Binding} markup extension in place of the
value that a particular property would ordinarily take. Many of the WPF markup
extensions enable an attribute syntax for properties where an attribute syntax would not
otherwise be possible. For example, a Style object is a relatively complex type that
contains a nested series of objects and properties. Styles in WPF are typically defined as
a resource in a ResourceDictionary, and then referenced through one of the two WPF
markup extensions that request a resource. The markup extension defers the evaluation
of the property value to a resource lookup and enables providing the value of the Style
property, taking type Style, in attribute syntax as in the following example:
For more information about markup extensions, see Markup Extensions and WPF XAML.
For a reference of markup extensions and other XAML programming features enabled in
the general .NET XAML implementation, see XAML Namespace (x:) Language Features.
For WPF-specific markup extensions, see WPF XAML Extensions.
Attached Properties
Attached properties are a programming concept introduced in XAML whereby
properties can be owned and defined by a particular type, but set as attributes or
property elements on any element. The primary scenario that attached properties are
intended for is to enable child elements in a markup structure to report information to a
parent element without requiring an extensively shared object model across all
elements. Conversely, attached properties can be used by parent elements to report
information to child elements. For more information on the purpose of attached
properties and how to create your own attached properties, see Attached Properties
Overview.
Attached properties use a syntax that superficially resembles property element syntax, in
that you also specify a typeName.propertyName combination. There are two important
differences:
You can also use property element syntax for attached properties. However, for
typical property element syntax, the typeName you specify is the object element
that contains the property element. If you are referring to an attached property,
then the typeName is the class that defines the attached property, not the
containing object element.
Attached Events
Attached events are another programming concept introduced in XAML where events
can be defined by a specific type, but handlers may be attached on any object element.
In the WOF implementation, often the type that defines an attached event is a static
type that defines a service, and sometimes those attached events are exposed by a
routed event alias in types that expose the service. Handlers for attached events are
specified through attribute syntax. As with attached events, the attribute syntax is
expanded for attached events to allow a typeName.eventName usage, where typeName
is the class that provides Add and Remove event handler accessors for the attached event
infrastructure, and eventName is the event name.
Attribute Description
elements of a Menu must be a MenuItem and are placed in the Items collection.
Sometimes the optional usages can help to visually clarify the object structure as
represented in the markup. Or sometimes an explicit property element usage can avoid
markup that is technically functional but visually confusing, such as nested markup
extensions within an attribute value.
XAML
<Button Background="Blue">Background</Button>
<Button Button.Background="Blue">Button.Background</Button>
<Button Control.Background="Blue">Control.Background</Button>
Button.Background works because the qualified lookup for that property on Button is
successful (Background was inherited from Control) and Button is the class of the object
element or a base class. Control.Background works because the Control class actually
defines Background and Control is a Button base class.
However, the following typeName.memberName form example does not work and is
thus shown commented:
XAML
Label is another derived class of Control, and if you had specified Label.Background
within a Label object element, this usage would have worked. However, because Label is
not the class or base class of Button, the specified XAML processor behavior is to then
process Label.Background as an attached property. Label.Background is not an available
attached property, and this usage fails.
XAML
<Button>Control.Background PE
<Control.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Yellow" Offset="0.0" />
<GradientStop Color="LimeGreen" Offset="1.0" />
</LinearGradientBrush>
</Control.Background>
</Button>
Here, the property element was given as Control.Background even though the property
element was contained in Button .
See also
XAML in WPF
XAML Namespace (x:) Language Features
WPF XAML Extensions
Dependency Properties Overview
TypeConverters and XAML
XAML and Custom Classes for WPF
Code-Behind and XAML in WPF
Article • 08/10/2023
Code-behind is a term used to describe the code that is joined with markup-defined
objects, when a XAML page is markup-compiled. This topic describes requirements for
code-behind as well as an alternative inline code mechanism for code in XAML.
Prerequisites
x:Code
Prerequisites
This topic assumes that you have read the XAML in WPF and have some basic
knowledge of the CLR and object-oriented programming.
Note that under the default behavior of the markup compile build actions, you can
leave the derivation blank in the partial class definition on the code-behind side.
The compiled result will assume the page root's backing type to be the basis for
the partial class, even if it not specified. However, relying on this behavior is not a
best practice.
The event handlers you write in the code-behind must be instance methods and
cannot be static methods. These methods must be defined by the partial class
within the CLR namespace identified by x:Class . You cannot qualify the name of
an event handler to instruct a XAML processor to look for an event handler for
event wiring in a different class scope.
The handler must match the delegate for the appropriate event in the backing type
system.
For the Microsoft Visual Basic language specifically, you can use the language-
specific Handles keyword to associate handlers with instances and events in the
handler declaration, instead of attaching handlers with attributes in XAML.
However, this technique does have some limitations because the Handles keyword
cannot support all of the specific features of the WPF event system, such as certain
routed event scenarios or attached events. For details, see Visual Basic and WPF
Event Handling.
x:Code
x:Code is a directive element defined in XAML. An x:Code directive element can contain
inline programming code. The code that is defined inline can interact with the XAML on
the same page. The following example illustrates inline C# code. Notice that the code is
inside the x:Code element and that the code must be surrounded by <CDATA[ ... ]]> to
escape the contents for XML, so that a XAML processor (interpreting either the XAML
schema or the WPF schema) will not try to interpret the contents literally as XML.
XAML
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyNamespace.MyCanvasCodeInline"
>
<Button Name="button1" Click="Clicked">Click Me!</Button>
<x:Code><![CDATA[
void Clicked(object sender, RoutedEventArgs e)
{
button1.Content = "Hello World";
}
]]></x:Code>
</Page>
See also
XAML in WPF
x:Code Intrinsic XAML Type
Building a WPF Application
XAML Syntax In Detail
XAML and Custom Classes for WPF
Article • 02/06/2023
The advantage of creating a class library is that any such custom classes can be
shared across many different possible applications. A separate library also makes
versioning issues of applications easier to control, and simplifies creating a class
where the intended class usage is as a root element on a XAML page.
The advantage of defining the custom classes in the application is that this
technique is relatively lightweight and minimizes the deployment and testing
issues encountered when you introduce separate assemblies beyond the main
application executable.
Your custom class must not be a nested class. Nested classes and the "dot" in their
general CLR usage syntax interfere with other WPF and/or XAML features such as
attached properties.
In addition to enabling object element syntax, your object definition also enables
property element syntax for any other public properties that take that object as the
value type. This is because the object can now be instantiated as an object element and
can fill the property element value of such a property.
Structures
Structures that you define as custom types are always able to be constructed in XAML in
WPF .This is because the CLR compilers implicitly create a parameterless constructor for
a structure that initializes all property values to their defaults. In some cases, the default
construction behavior and/or object element usage for a structure is not desirable. This
might be because the structure is intended to fill values and function conceptually as a
union, where the values contained might have mutually exclusive interpretations and
thus none of its properties are settable. A WPF example of such a structure is
GridLength. Generally, such structures should implement a type converter such that the
values can be expressed in attribute form, using string conventions that create the
different interpretations or modes of the structure's values. The structure should also
expose similar behavior for code construction through a non-parameterless constructor.
Alternatively, the property may reference an abstract class type, or an interface. For
abstract classes or interfaces, the expectation for XAML parsing is that the property
value must be filled with practical class instances that implement the interface, or
instances of types that derive from the abstract class.
Properties can be declared on an abstract class, but can only be set on practical classes
that derive from the abstract class. This is because creating the object element for the
class at all requires a public parameterless constructor on the class.
XAML
<Button>Hallo!
<Button.Language>
de-DE
</Button.Language>
</Button>
XAML
<Button Language="de-DE">Hallo!</Button>
Examples of properties where attribute syntax is allowed but property element syntax
that contains an object element is disallowed through XAML are various properties that
take the Cursor type. The Cursor class has a dedicated type converter CursorConverter,
but does not expose a parameterless constructor, so the Cursor property can only be set
through attribute syntax even though the actual Cursor type is a reference type.
Whenever you expose a property that has a XAML usage, particularly if you are a control
author, you should strongly consider backing that property with a dependency property.
This is particularly true if you use the existing Windows Presentation Foundation (WPF)
implementation of the XAML processor, because you can improve performance by using
DependencyProperty backing. A dependency property will expose property system
features for your property that users will come to expect for a XAML accessible property.
This includes features such as animation, data binding, and style support. For more
information, see Custom Dependency Properties and XAML Loading and Dependency
Properties.
7 Note
It is possible to register handlers directly for routed events using AddHandler, and
to deliberately not define a CLR event that exposes the routed event. This is not
generally recommended because the event will not enable XAML attribute syntax
for attaching handlers, and your resulting class will offer a less transparent XAML
view of that type's capabilities.
The object that is the collection object does not need to be specified in object
element syntax. The presence of that collection type is implicit whenever you
specify a property in XAML that takes a collection type.
The .NET Framework XAML Services implementation and thus the WPF XAML processor
uses the following definition for what constitutes a collection property. The property
type of the property must implement one of the following:
Implements IList.
Implements IDictionary.
Derives from Array (for more information about arrays in XAML, see x:Array
Markup Extension.)
Each of these types in CLR has an Add method, which is used by the XAML processor to
add items to the underlying collection when creating the object graph.
7 Note
When you declare a property that takes a collection, be cautious about how that
property value is initialized in new instances of the type. If you are not implementing the
property as a dependency property, then having the property use a backing field that
calls the collection type constructor is adequate. If your property is a dependency
property, then you may need to initialize the collection property as part of the default
type constructor. This is because a dependency property takes its default value from
metadata, and you typically do not want the initial value of a collection property to be a
static, shared collection. There should be a collection instance per each containing type
instance. For more information, see Custom Dependency Properties.
You can implement a custom collection type for your collection property. Because of
implicit collection property treatment, the custom collection type does not need to
provide a parameterless constructor in order to be used in XAML implicitly. However,
you can optionally provide a parameterless constructor for the collection type. This can
be a worthwhile practice. Unless you do provide a parameterless constructor, you
cannot explicitly declare the collection as an object element. Some markup authors
might prefer to see the explicit collection as a matter of markup style. Also, a
parameterless constructor can simplify the initialization requirements when you create
new objects that use your collection type as a property value.
You can specify a collection property to be the XAML content property. This results in a
usage for that property whereby the object element can have one or more child
elements, without any intervening collection object elements or property element tags.
These elements are then treated as the value for the XAML content property and added
to the backing collection instance.
Some existing XAML content properties use the property type of Object . This enables a
XAML content property that can take primitive values such as a String as well as taking a
single reference object value. If you follow this model, your type is responsible for type
determination as well as the handling of possible types. The typical reason for an Object
content type is to support both a simple means of adding object content as a string
(which receives a default presentation treatment), or an advanced means of adding
object content that specifies a non-default presentation or additional data.
Serializing XAML
For certain scenarios, such as if you are a control author, you may also want to assure
that any object representation that can be instantiated in XAML can also be serialized
back to equivalent XAML markup. Serialization requirements are not described in this
topic. See Control Authoring Overview and Element Tree and Serialization.
See also
XAML in WPF
Custom Dependency Properties
Control Authoring Overview
Base Elements Overview
XAML Loading and Dependency Properties
Markup Extensions and WPF XAML
Article • 02/06/2023
This topic introduces the concept of markup extensions for XAML, including their syntax
rules, purpose, and the class object model that underlies them. Markup extensions are a
general feature of the XAML language and of the .NET implementation of XAML
services. This topic specifically details markup extensions for use in WPF XAML.
When used to provide an attribute value, the syntax that distinguishes a markup
extension sequence to a XAML processor is the presence of the opening and closing
curly braces ({ and }). The type of markup extension is then identified by the string token
immediately following the opening curly brace.
When used in property element syntax, a markup extension is visually the same as any
other element used to provide a property element value: a XAML element declaration
that references the markup extension class as an element, enclosed within angle
brackets (<>).
x:Type supplies the Type object for the named type. This facility is used most
frequently in styles and templates. For details, see x:Type Markup Extension.
x:Static produces static values. The values come from value-type code entities
that are not directly the type of a target property's value, but can be evaluated to
that type. For details, see x:Static Markup Extension.
x:Null specifies null as a value for a property and can be used either for
attributes or property element values. For details, see x:Null Markup Extension.
x:Array provides support for creation of general arrays in XAML syntax, for cases
where the collection support provided by WPF base elements and control models
is deliberately not used. For details, see x:Array Markup Extension.
7 Note
The x: prefix is used for the typical XAML namespace mapping of the XAML
language intrinsics, in the root element of a XAML file or production. For example,
the Visual Studio templates for WPF applications initiate a XAML file using this x:
mapping. You could choose a different prefix token in your own XAML namespace
mapping, but this documentation will assume the default x: mapping as a means
of identifying those entities that are a defined part of the XAML namespace for the
XAML language, as opposed to the WPF default namespace or other XAML
namespaces not related to a specific framework.
Binding provides a data bound value for a property, using the data context that
applies to the parent object at run time. This markup extension is relatively
complex, because it enables a substantial inline syntax for specifying a data
binding. For details, see Binding Markup Extension.
several possible relationships in the run-time object tree. This provides specialized
sourcing for bindings that are created in multi-use templates or created in code
without full knowledge of the surrounding object tree. For details, see
RelativeSource MarkupExtension.
*Extension Classes
For both the general XAML language and WPF-specific markup extensions, the behavior
of each markup extension is identified to a XAML processor through a *Extension class
that derives from MarkupExtension, and provides an implementation of the
ProvideValue method. This method on each extension provides the object that is
returned when the markup extension is evaluated. The returned object is typically
evaluated based on the various string tokens that are passed to the markup extension.
Some markup extensions do not use string token arguments. This is either because they
return a static or consistent value, or because context for what value should be returned
is available through one of the services passed through the serviceProvider parameter.
The *Extension naming pattern is for convenience and consistency. It is not necessary in
order for a XAML processor to identify that class as support for a markup extension. So
long as your codebase includes System.Xaml and uses .NET Framework XAML Services
implementations, all that is necessary to be recognized as a XAML markup extension is
to derive from MarkupExtension and to support a construction syntax. WPF defines
markup extension-enabling classes that do not follow the *Extension naming pattern,
for example Binding. Typically the reason for this is that the class supports scenarios
beyond pure markup extension support. In the case of Binding, that class supports run-
time access to methods and properties of the object for scenarios that have nothing to
do with XAML.
If the individual separated tokens do not contain any equals signs, each token is
treated as a constructor argument. Each constructor parameter must be given as
the type expected by that signature, and in the proper order expected by that
signature.
7 Note
A XAML processor must call the constructor that matches the argument count
of the number of pairs. For this reason, if you are implementing a custom
markup extension, do not provide multiple constructors with the same
argument count. The behavior for how a XAML processor behaves if more
than one markup extension constructor path with the same parameter count
exists is not defined, but you should anticipate that a XAML processor is
permitted to throw an exception on usage if this situation exists in the markup
extension type definitions.
If the individual separated tokens contain equals signs, then a XAML processor first
calls the parameterless constructor for the markup extension. Then, each
name=value pair is interpreted as a property name that exists on the markup
extension, and a value to assign to that property.
If there is a parallel result between the constructor behavior and the property
setting behavior in a markup extension, it does not matter which behavior you use.
It is more common usage to use the property = value pairs for markup extensions
that have more than one settable property, if only because it makes your markup
more intentional and you are less likely to accidentally transpose constructor
parameters. (When you specify property=value pairs, those properties may be in
any order.) Also, there is no guarantee that a markup extension supplies a
constructor parameter that sets every one of its settable properties. For example,
Binding is a markup extension, with many properties that are settable through the
extension in property = value form, but Binding only supports two constructors: a
parameterless constructor, and one that sets an initial path.
<Setter Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
In this usage, the x:Static statement is evaluated first and returns a string. That string
is then used as the argument for DynamicResource .
Most markup extensions, when used in object element syntax to fill a property element,
would not have content or any further property element syntax within. Thus you would
close the object element tag, and provide no child elements. Whenever any object
element is encountered by a XAML processor, the constructor for that class is called,
which instantiates the object created from the parsed element. A markup extension class
is no different: if you want your markup extension to be usable in object element syntax,
you must provide a parameterless constructor. Some existing markup extensions have at
least one required property value that must be specified for effective initialization. If so,
that property value is typically given as a property attribute on the object element. In
the XAML Namespace (x:) Language Features and WPF XAML Extensions reference
pages, markup extensions that have required properties (and the names of required
properties) will be noted. Reference pages will also note if either object element syntax
or attribute syntax is disallowed for particular markup extensions. A notable case is
x:Array Markup Extension, which cannot support attribute syntax because the contents
of that array must be specified within the tagging as content. The array contents are
handled as general objects, therefore no default type converter for the attribute is
feasible. Also, x:Array Markup Extension requires a type parameter.
See also
XAML in WPF
XAML Namespace (x:) Language Features
WPF XAML Extensions
StaticResource Markup Extension
Binding Markup Extension
DynamicResource Markup Extension
x:Type Markup Extension
XAML Namespaces and Namespace
Mapping for WPF XAML
Article • 03/17/2022
This topic further explains the presence and purpose of the two XAML namespace
mappings as often found in the root tag of a WPF XAML file. It also describes how to
produce similar mappings for using elements that are defined in your own code, and/or
within separate assemblies.
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
The second declaration maps a separate XAML namespace, mapping it (typically) to the
x: prefix.
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
The relationship between these declarations is that the x: prefix mapping supports the
intrinsics that are part of the XAML language definition, and WPF is one implementation
that uses XAML as a language and defines a vocabulary of its objects for XAML. Because
the WPF vocabulary's usages will be far more common than the XAML intrinsics usages,
the WPF vocabulary is mapped as the default.
The x: prefix convention for mapping the XAML language intrinsics support is followed
by project templates, sample code, and the documentation of language features within
this SDK. The XAML namespace defines many commonly-used features that are
necessary even for basic WPF applications. For instance, in order to join any code-
behind to a XAML file through a partial class, you must name that class as the x:Class
attribute in the root element of the relevant XAML file. Or, any element as defined in a
XAML page that you wish to access as a keyed resource should have the x:Key attribute
set on the element in question. For more information on these and other aspects of
XAML see XAML in WPF or XAML Syntax In Detail.
The syntax takes the following possible named tokens and following values:
clr-namespace: The CLR namespace declared within the assembly that contains the
assembly= The assembly that contains some or all of the referenced CLR namespace.
This value is typically just the name of the assembly, not the path, and does not include
the extension (such as .dll or .exe). The path to that assembly must be established as a
project reference in the project file that contains the XAML you are trying to map. In
order to incorporate versioning and strong-name signing, the assembly value can be a
string as defined by AssemblyName, rather than the simple string name.
Note that the character separating the clr-namespace token from its value is a colon (:)
whereas the character separating the assembly token from its value is an equals sign (=).
The character to use between these two tokens is a semicolon. Also, do not include any
white space anywhere in the declaration.
namespace SDKSample {
public class ExampleClass : ContentControl {
public ExampleClass() {
...
}
}
}
This custom class is then compiled into a library, which per the project settings (not
shown) is named SDKSampleLibrary .
In order to reference this custom class, you also need to include it as a reference for
your current project, which you would typically do using the Solution Explorer UI in
Visual Studio.
Now that you have a library containing a class, and a reference to it in project settings,
you can add the following prefix mapping as part of your root element in XAML:
xmlns:custom="clr-namespace:SDKSample;assembly=SDKSampleLibrary"
To put it all together, the following is XAML that includes the custom mapping along
with the typical default and x: mappings in the root tag, then uses a prefixed reference
to instantiate ExampleClass in that UI:
XAML
<Page x:Class="WPFApplication1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:custom="clr-namespace:SDKSample;assembly=SDKSampleLibrary">
...
<custom:ExampleClass/>
...
</Page>
WPF Designer for Visual Studio uses a designer namespace that is typically mapped to
the prefix d: . More recent project templates for WPF might pre-map this XAML
namespace to support interchange of the XAML between WPF Designer for Visual
Studio and other design environments. This design XAML namespace is used to
perpetuate design state while roundtripping XAML-based UI in the designer. It is also
used for features such as d:IsDataSource , which enable runtime data sources in a
designer.
Another prefix you might see mapped is mc: . mc: is for markup compatibility, and is
leveraging a markup compatibility pattern that is not necessarily XAML-specific. To some
extent, the markup compatibility features can be used to exchange XAML between
frameworks or across other boundaries of backing implementation, work between XAML
schema contexts, provide compatibility for limited modes in designers, and so on. For
more information on markup compatibility concepts and how they relate to WPF, see
Markup Compatibility (mc:) Language Features.
3. If the short name + public key token of a qualified name matches the assembly
that the markup was loaded from, return that assembly.
Compiled XAML for WPF (generated via XamlBuildTask) does not use the already-loaded
assemblies from AppDomain (Step 1). Also, the name should never be unqualified from
XamlBuildTask output, so Step 5 does not apply.
Compiled BAML (generated via PresentationBuildTask) uses all steps, although BAML
also should not contain unqualified assembly names.
See also
Understanding XML Namespaces
XAML in WPF
WPF XAML Namescopes
Article • 02/06/2023
XAML namescopes are a concept that identifies objects that are defined in XAML. The
names in a XAML namescope can be used to establish relationships between the XAML-
defined names of objects and their instance equivalents in an object tree. Typically,
XAML namescopes in WPF managed code are created when loading the individual
XAML page roots for a XAML application. XAML namescopes as the programming
object are defined by the INameScope interface and are also implemented by the
practical class NameScope.
In WPF XAML, elements that are common root elements (such as Page, and Window)
always control a XAML namescope. If an element such as FrameworkElement or
FrameworkContentElement is the root element of the page in markup, a XAML
processor adds a Page root implicitly so that the Page can provide a working XAML
namescope.
7 Note
WPF build actions create a XAML namescope for a XAML production even if no
Name or x:Name attributes are defined on any elements in the XAML markup.
If you try to use the same name twice in any XAML namescope, an exception is raised.
For WPF XAML that has code-behind and is part of a compiled application, the
exception is raised at build time by WPF build actions, when creating the generated
class for the page during the initial markup compile. For XAML that is not markup-
compiled by any build action, exceptions related to XAML namescope issues might be
raised when the XAML is loaded. XAML designers might also anticipate XAML
namescope issues at design time.
The most common scenario for application developers is that you will use RegisterName
to register names into the XAML namescope on the current root of the page.
RegisterName is part of an important scenario for storyboards that target objects for
animations. For more information, see Storyboards Overview.
If you call RegisterName on an object other than the object that defines the XAML
namescope, the name is still registered to the XAML namescope that the calling object
is held within, as if you had called RegisterName on the XAML namescope defining
object.
For applications that are created programmatically, and not from loaded XAML, the
object that defines a XAML namescope must implement INameScope, or be a
FrameworkElement or FrameworkContentElement derived class, in order to support
creation of a XAML namescope on its instances.
Also, for any element that is not loaded and processed by a XAML processor, the XAML
namescope for the object is not created or initialized by default. You must explicitly
create a new XAML namescope for any object that you intend to register names into
subsequently. To create a XAML namescope, you call the static SetNameScope method.
Specify the object that will own it as the dependencyObject parameter, and a new
NameScope constructor call as the value parameter.
For an example of using XAML namescope APIs in code, see Define a Name Scope.
XAML
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Page.Resources>
<ControlTemplate x:Key="MyButtonTemplate" TargetType="{x:Type Button}">
<Border BorderBrush="Red" Name="TheBorder" BorderThickness="2">
<ContentPresenter/>
</Border>
</ControlTemplate>
</Page.Resources>
<StackPanel>
<Button Template="{StaticResource MyButtonTemplate}">My first
button</Button>
<Button Template="{StaticResource MyButtonTemplate}">My second
button</Button>
</StackPanel>
</Page>
Here, the same template is applied to two different buttons. If templates did not have
discrete XAML namescopes, the TheBorder name used in the template would cause a
name collision in the XAML namescope. Each instantiation of the template has its own
XAML namescope, so in this example each instantiated template's XAML namescope
would contain exactly one name.
Styles also define their own XAML namescope, mostly so that parts of storyboards can
have particular names assigned. These names enable control specific behaviors that will
target elements of that name, even if the template was re-defined as part of control
customization.
If you are a control author and you are generating a convention where a particular
named element in an applied template is the target for a behavior that is defined by the
control itself, you can use the GetTemplateChild method from your control
implementation code. The GetTemplateChild method is protected, so only the control
author has access to it.
If you are working from within a template, and need to get to the XAML namescope
where the template is applied, get the value of TemplatedParent, and then call
FindName there. An example of working within the template would be if you are writing
the event handler implementation where the event will be raised from an element in an
applied template.
SetNameScope is used to map a new XAML namescope to an existing object. You can
call SetNameScope more than once in order to reset or clear the XAML namescope, but
that is not a common usage. Also, GetNameScope is not typically used from code.
XAML Namescope Implementations
The following classes implement INameScope directly:
NameScope
Style
ResourceDictionary
FrameworkTemplate
ResourceDictionary does not use XAML names or namescopes ; it uses keys instead,
because it is a dictionary implementation. The only reason that ResourceDictionary
implements INameScope is so it can raise exceptions to user code that help clarify the
distinction between a true XAML namescope and how a ResourceDictionary handles
keys, and also to assure that XAML namescopes are not applied to a ResourceDictionary
by parent elements.
The following classes define their own XAML namescope, by using the
System.Windows.NameScope helper class and connecting to its XAML namescope
implementation through the NameScope.NameScope attached property:
FrameworkElement
FrameworkContentElement
See also
XAML Namespaces and Namespace Mapping for WPF XAML
x:Name Directive
Inline Styles and Templates
Article • 08/10/2023
Windows Presentation Foundation (WPF) provides Style objects and template objects
(FrameworkTemplate subclasses) as a way to define the visual appearance of an element
in resources, so that they can be used multiple times. For this reason, attributes in XAML
that take the types Style and FrameworkTemplate almost always make resource
references to existing styles and templates rather than define new ones inline.
The attribute usage is much more common. A style that is defined inline and not
defined in resources is necessarily scoped to the containing element only, and cannot be
re-used as easily because it has no resource key. In general a resource-defined style is
more versatile and useful, and is more in keeping with the general Windows
Presentation Foundation (WPF) programming model principle of separating program
logic in code from design in markup.
Usually there is no reason to set a style or template inline, even if you only intend to use
that style or template in that location. Most elements that can take a style or template
also support a content property and a content model. If you are only using whatever
logical tree you create through styling or templating once, it would be even easier to
just fill that content property with the equivalent child elements in direct markup. This
would bypass the style and template mechanisms altogether.
Other syntaxes enabled by markup extensions that return an object are also possible for
styles and templates. Two such extensions that have possible scenarios include
TemplateBinding and Binding.
See also
Styling and Templating
TypeConverters and XAML
Article • 02/06/2023
This topic introduces the purpose of type conversion from string as a general XAML
language feature. In the .NET Framework, the TypeConverter class serves a particular
purpose as part of the implementation for a managed custom class that can be used as
a property value in XAML attribute usage. If you write a custom class, and you want
instances of your class to be usable as XAML settable attribute values, you might need
to apply a TypeConverterAttribute to your class, write a custom TypeConverter class, or
both.
Even this simple type of Point and its simple usage in XAML involve a type converter. In
this case that is the class PointConverter.
The type converter for Point defined at the class level streamlines the markup usages of
all properties that take Point. Without a type converter here, you would need the
following much more verbose markup for the same example shown previously:
XAML
<LinearGradientBrush>
<LinearGradientBrush.StartPoint>
<Point X="0" Y="0"/>
</LinearGradientBrush.StartPoint>
<LinearGradientBrush.EndPoint>
<Point X="1" Y="1"/>
</LinearGradientBrush.EndPoint>
</LinearGradientBrush>
Whether to use the type conversion string or a more verbose equivalent syntax is
generally a coding style choice. Your XAML tooling workflow might also influence how
values are set. Some XAML tools tend to emit the most verbose form of the markup
because it is easier to round-trip to designer views or its own serialization mechanism.
Existing type converters can generally be discovered on WPF and .NET Framework types
by checking a class (or property) for the presence of an applied TypeConverterAttribute.
This attribute will name the class that is the supporting type converter for values of that
type, for XAML purposes as well as potentially other purposes.
TypeConverter
In the Point example given previously, the class PointConverter was mentioned. For .NET
implementations of XAML, all type converters that are used for XAML purposes are
classes that derive from the base class TypeConverter. The TypeConverter class existed in
versions of .NET Framework that precede the existence of XAML; one of its original
usages was to provide string conversion for property dialogs in visual designers. For
XAML, the role of TypeConverter is expanded to include being the base class for to-
string and from-string conversions that enable parsing a string attribute value, and
possibly processing a run-time value of a particular object property back into a string for
serialization as an attribute.
TypeConverter defines four members that are relevant for converting to and from
strings for XAML processing purposes:
CanConvertTo
CanConvertFrom
ConvertTo
ConvertFrom
Of these, the most important method is ConvertFrom. This method converts the input
string to the required object type. Strictly speaking, the ConvertFrom method could be
implemented to convert a much wider range of types into the converter's intended
destination type, and thus serve purposes that extend beyond XAML such as supporting
run-time conversions, but for XAML purposes it is only the code path that can process a
String input that matters.
CanConvertTo and CanConvertFrom are support methods that are used when a service
queries the capabilities of the TypeConverter implementation. You must implement
these methods to return true for type-specific cases that the equivalent conversion
methods of your converter support. For XAML purposes, this generally means the String
type.
As an example where culture can be an issue, some cultures use a comma as their
decimal point delimiter for numbers. This will collide with the behavior that many of the
WPF XAML type converters have, which is to use a comma as a delimiter (based on
historical precedents such as the common X,Y form, or comma delimited lists). Even
passing a culture in the surrounding XAML (setting Language or xml:lang to the sl-SI
culture, an example of a culture that uses a comma for decimal in this way) does not
solve the issue.
Implementing ConvertFrom
To be usable as a TypeConverter implementation that supports XAML, the ConvertFrom
method for that converter must accept a string as the value parameter. If the string was
in valid format, and can be converted by the TypeConverter implementation, then the
returned object must support a cast to the type expected by the property. Otherwise,
the ConvertFrom implementation must return null .
Each TypeConverter implementation can have its own interpretation of what constitutes
a valid string for a conversion, and can also use or ignore the type description or culture
contexts passed as parameters. However, the WPF XAML processing might not pass
values to the type description context in all cases, and also might not pass culture based
on xml:lang .
7 Note
Do not use the curly brace characters, particularly {, as a possible element of your
string format. These characters are reserved as the entry and exit for a markup
extension sequence.
Implementing ConvertTo
ConvertTo is potentially used for serialization support. Serialization support through
ConvertTo for your custom type and its type converter is not an absolute requirement.
However, if you are implementing a control, or using serialization of as part of the
features or design of your class, you should implement ConvertTo.
If the value cannot be serialized, or the converter does not support serialization, the
ConvertTo implementation must return null , and is permitted to throw an exception in
this case. But if you do throw exceptions, you should report the inability to use that
conversion as part of your CanConvertTo implementation so that the best practice of
checking with CanConvertTo first to avoid exceptions is supported.
If destinationType parameter is not of type String, you can choose your own converter
handling. Typically, you would revert to base implementation handling, which in the
basemost ConvertTo raises a specific exception.
Implementing CanConvertTo
Your CanConvertTo implementation should return true for destinationType of type
String, and otherwise defer to the base implementation.
Implementing CanConvertFrom
Your CanConvertFrom implementation should return true for sourceType of type String,
and otherwise defer to the base implementation.
You can also provide a type converter on a per-property basis. Instead of applying a
TypeConverterAttribute to the class definition, apply it to a property definition (the main
definition, not the get / set implementations within it). The type of the property must
match the type that is processed by your custom type converter. With this attribute
applied, when a XAML processor handles values of that property, it can process input
strings and return object instances. The per-property type converter technique is
particularly useful if you choose to use a property type from Microsoft .NET Framework
or from some other library where you cannot control the class definition and cannot
apply a TypeConverterAttribute there.
See also
TypeConverter
XAML in WPF
Markup Extensions and WPF XAML
XAML Syntax In Detail
WPF XAML Extensions
Article • 02/06/2023
In This Section
Binding Markup Extension
ColorConvertedBitmap Markup Extension
ComponentResourceKey Markup Extension
DynamicResource Markup Extension
RelativeSource MarkupExtension
StaticResource Markup Extension
TemplateBinding Markup Extension
ThemeDictionary Markup Extension
PropertyPath XAML Syntax
PresentationOptions:Freeze Attribute
Binding Markup Extension
Article • 02/06/2023
Syntax Notes
In these syntaxes, the [] and * are not literals. They are part of a notation to indicate
that zero or more bindProp = value pairs can be used, with a , separator between them
and preceding bindProp = value pairs.
Any of the properties listed in the "Binding Properties That Can Be Set with the Binding
Extension" section could instead be set using attributes of a Binding object element.
However, that is not truly the markup extension usage of Binding, it is just the general
XAML processing of attributes that set properties of the CLR Binding class. In other
words, <Binding bindProp1 =" value1 "[ bindPropN =" valueN "]*/> is an equivalent
syntax for attributes of Binding object element usage instead of a Binding expression
usage. To learn about the XAML attribute usage of specific properties of Binding, see the
"XAML Attribute Usage" section of the relevant property of Binding in the .NET
Framework Class Library.
XAML Values
Value Description
Value Description
bindProp1, The name of the Binding or BindingBase property to set. Not all Binding properties
bindPropN can be set with the Binding extension, and some properties are settable within a
Binding expression only by using further nested markup extensions. See "Binding
Properties That Can Be Set with the Binding Extension" section.
value1, The value to set the property to. The handling of the attribute value is ultimately
valueN specific to the type and logic of the specific Binding property being set.
path The path string that sets the implicit Binding.Path property. See also PropertyPath
XAML Syntax.
Unqualified {Binding}
The {Binding} usage shown in "Binding Expression Usage" creates a Binding object with
default values, which includes an initial Binding.Path of null . This is still useful in many
scenarios, because the created Binding might be relying on key data binding properties
such as Binding.Path and Binding.Source being set in the run-time data context. For
more information on the concept of data context, see Data Binding.
Implicit Path
The Binding markup extension uses Binding.Path as a conceptual "default property",
where Path= does not need to appear in the expression. If you specify a Binding
expression with an implicit path, the implicit path must appear first in the expression,
prior to any other bindProp = value pairs where the Binding property is specified by
name. For example: {Binding PathString} , where PathString is a string that is
evaluated to be the value of Binding.Path in the Binding created by the markup
extension usage. You can append an implicit path with other named properties after the
comma separator, for example, {Binding LastName, Mode=TwoWay} .
Several of these property values require object types that do not support a native type
conversion from a text syntax in XAML, and thus require markup extensions in order to
be set as an attribute value. Check the XAML Attribute Usage section in the .NET
Framework Class Library for each property for more information; the string you use for
XAML attribute syntax with or without further markup extension usage is basically the
same as the value you specify in a Binding expression, with the exception that you do
not place quotation marks around each bindProp = value in the Binding expression.
FallbackValue: can be set as a bindProp = value string in the expression, but this is
dependent on the type of the value being passed. If passing a reference type,
requires an object reference such as a nested StaticResource Markup Extension.
Mode: value is a constant name from the BindingMode enumeration. For example,
{Binding Mode=OneWay} .
Path: a string that describes a path into a data object or a general object model.
The format provides several different conventions for traversing an object model
that cannot be adequately described in this topic. See PropertyPath XAML Syntax.
StringFormat: a string that describes a string format convention for the bound
data. This is a relatively advanced binding concept; see reference page for
StringFormat.
TargetNullValue: can be set as a bindProp = value string in the expression, but this
is dependent on the type of the parameter being passed. If passing a reference
type for the value, requires an object reference such as a nested StaticResource
Markup Extension.
XPath: a string that describes a path into the XMLDOM of an XML data source. See
Bind to XML Data Using an XMLDataProvider and XPath Queries.
The following are properties of Binding that cannot be set using the Binding markup
extension/ {Binding} expression form.
XmlNamespaceManager
Remarks
) Important
Describing data binding at a basic level is not covered in this topic. See Data Binding
Overview.
7 Note
Boolean values for XAML are case insensitive. For example you could specify either
{Binding NotifyOnValidationError=true} or {Binding NotifyOnValidationError=True} .
Bindings that involve data validation are typically specified by an explicit Binding
element rather than as a {Binding ...} expression, and setting ValidatesOnDataErrors
or ValidatesOnExceptions in an expression is uncommon. This is because the companion
property ValidationRules cannot be readily set in the expression form. For more
information, see Implement Binding Validation.
Binding is a markup extension. Markup extensions are typically implemented when
Binding is an atypical markup extension in that the Binding class that implements the
extension functionality for WPF's XAML implementation also implements several other
methods and properties that are not related to XAML. The other members are intended
to make Binding a more versatile and self-contained class that can address many data
binding scenarios in addition to functioning as a XAML markup extension.
See also
Binding
Data Binding Overview
XAML in WPF
Markup Extensions and WPF XAML
ColorConvertedBitmap Markup
Extension
Article • 02/06/2023
Provides a way to specify a bitmap source that does not have an embedded profile.
Color contexts / profiles are specified by URI, as is the image source URI.
XAML Values
Value Description
Remarks
This markup extension is intended to fill a related set of image-source property values
such as UriSource.
Attribute syntax is the most common syntax used with this markup extension.
ColorConvertedBitmap (or ColorConvertedBitmapExtension ) cannot be used in property
element syntax, because the values can only be set as values on the initial constructor,
which is the string following the extension identifier.
See also
UriSource
Markup Extensions and WPF XAML
Imaging Overview
ComponentResourceKey Markup
Extension
Article • 02/06/2023
Defines and references keys for resources that are loaded from external assemblies. This
enables a resource lookup to specify a target type in an assembly, rather than an explicit
resource dictionary in an assembly or on a class.
targetTypeName The name of the public common language runtime (CLR) type that is defined in
the resource assembly.
targetID The key for the resource. When resources are looked up, targetID will be
analogous to the x:Key Directive of the resource.
Remarks
As seen in the usages above, a { ComponentResourceKey } markup extension usage is found
in two places:
Accessing a theme resource from the assembly, when you are retemplating the
control but want to use property values that come from resources provided by the
control's themes.
The TypeInTargetAssembly identifies a type that exists in the target assembly where the
resource is actually defined. A ComponentResourceKey can be defined and used
independently of knowing exactly where the TypeInTargetAssembly is defined, but
eventually must resolve the type through referenced assemblies.
A common usage for ComponentResourceKey is to define keys that are then exposed as
members of a class. For this usage, you use the ComponentResourceKey class
constructor, not the markup extension. For more information, see
ComponentResourceKey, or the "Defining and Referencing Keys for Theme Resources"
section of the topic Control Authoring Overview.
For both establishing keys and referencing keyed resources, attribute syntax is
commonly used for the ComponentResourceKey markup extension.
Technically, the value for targetID can be any object, it does not have to be a string.
However, the most common usage in WPF is to align the targetID value with forms that
are strings, and where such strings are valid in the XamlName Grammar.
ComponentResourceKey can be used in object element syntax. In this case, specifying the
In the WPF XAML reader implementation, the handling for this markup extension is
defined by the ComponentResourceKey class.
See also
ComponentResourceKey
ControlTemplate
Control Authoring Overview
XAML in WPF
Markup Extensions and WPF XAML
DateTime XAML Syntax
Article • 02/06/2023
Some controls, such as Calendar and DatePicker, have properties that use the DateTime
type. Although you typically specify an initial date or time for these controls in the code-
behind at run time, you can specify an initial date or time in XAML. The WPF XAML
parser handles parsing of DateTime values using a built-in XAML text syntax. This topic
describes the specifics of the DateTime XAML text syntax.
When specifying a DateTime in XAML, you can use any of the format strings
interchangeably.
You can also use formats and format strings that are not specifically shown in this topic.
Technically, the XAML for any DateTime value that is specified and then parsed by the
WPF XAML parser uses an internal call to DateTime.Parse, therefore you could use any
string accepted by DateTime.Parse for your XAML input. For more information, see
DateTime.Parse.
) Important
The DateTime XAML syntax always uses en-us as the CultureInfo for its native
conversion. This is not influenced by Language value or xml:lang value in the
XAML, because XAML attribute-level type conversion acts without that context. Do
not attempt to interpolate the format strings shown here due to cultural variations,
such as the order in which day and month appear. The format strings shown here
are the exact format strings used when parsing the XAML regardless of other
culture settings.
The following sections describe some of the common DateTime format strings.
M/d/YYYY
This is the simplest form that specifies all necessary information for typical usages by
WPF controls, and cannot be influenced by accidental time zone offsets versus a time
component, and is therefore recommended over the other formats.
For example, to specify the date of June 1, 2010, use the following string:
3/1/2010
yyyy'-'MM'-'dd'T'HH':'mm':'ss
For example, to specify the date of June 1, 2010, use the following string (time
components are all entered as 0):
2010-06-01T000:00:00
RFC1123 Pattern ("r")
The RFC1123 pattern is useful because it could be a string input from other date
generators that also use the RFC1123 pattern for culture invariant reasons. The following
shows the RFC1123 DateTime pattern in XAML:
For example, to specify the date of June 1, 2010, use the following string (time
components are all entered as 0):
See also
XAML in WPF
DynamicResource Markup Extension
Article • 02/06/2023
Provides a value for any XAML property attribute by deferring that value to be a
reference to a defined resource. Lookup behavior for that resource is analogous to run-
time lookup.
<object>
<object.property>
<DynamicResource ResourceKey="key" ... />
</object.property>
</object>
XAML Values
Value Description
key The key for the requested resource. This key was initially assigned by the x:Key Directive if
a resource was created in markup, or was provided as the key parameter when calling
ResourceDictionary.Add if the resource was created in code.
Remarks
A DynamicResource will create a temporary expression during the initial compilation and
thus defer lookup for resources until the requested resource value is actually required in
order to construct an object. This may potentially be after the XAML page is loaded. The
resource value will be found based on key search against all active resource dictionaries
starting from the current page scope, and is substituted for the placeholder expression
from compilation.
) Important
A resource key may be any string defined in the XamlName Grammar. A resource key
may also be other object types, such as a Type. A Type key is fundamental to how
controls can be styled by themes. For more information, see Control Authoring
Overview.
APIs for lookup of resource values, such as FindResource, follow the same resource
lookup logic as used by DynamicResource .
Attribute syntax is the most common syntax used with this markup extension. The string
token provided after the DynamicResource identifier string is assigned as the
ResourceKey value of the underlying DynamicResourceExtension extension class.
DynamicResource can be used in object element syntax. In this case, specifying the value
DynamicResource can also be used in a verbose attribute usage that specifies the
ResourceKey property as a property=value pair:
XML
<object property="{DynamicResource ResourceKey=key}" ... />
The verbose usage is often useful for extensions that have more than one settable
property, or if some properties are optional. Because DynamicResource has only one
settable property, which is required, this verbose usage is not typical.
In the WPF XAML processor implementation, the handling for this markup extension is
defined by the DynamicResourceExtension class.
when there is a requirement to escape attribute values to be other than literal values or
handler names, and the requirement is more global than just putting type converters on
certain types or properties. All markup extensions in XAML use the { and } characters in
their attribute syntax, which is the convention by which a XAML processor recognizes
that a markup extension must process the attribute. For more information, see Markup
Extensions and WPF XAML.
See also
XAML Resources
Resources and Code
x:Key Directive
XAML in WPF
Markup Extensions and WPF XAML
StaticResource Markup Extension
Markup Extensions and WPF XAML
RelativeSource MarkupExtension
Article • 03/17/2022
<Binding>
<Binding.RelativeSource>
<RelativeSource Mode="modeEnumValue"/>
</Binding.RelativeSource>
</Binding>
-or-
XML
<Binding>
<Binding.RelativeSource>
<RelativeSource
Mode="FindAncestor"
AncestorType="{x:Type typeName}"
AncestorLevel="intLevel"
/>
</Binding.RelativeSource>
</Binding>
XAML Values
Value Description
FindAncestor The string token FindAncestor . Using this token enters a mode whereby a
RelativeSource specifies an ancestor type and optionally an ancestor level. This
corresponds to a RelativeSource as created with its Mode property set to
FindAncestor.
typeName Required for FindAncestor mode. The name of a type, which fills the
AncestorType property.
intLevel Optional for FindAncestor mode. An ancestor level (evaluated towards the
parent direction in the logical tree).
Remarks
{RelativeSource TemplatedParent} binding usages are a key technique that addresses a
larger concept of the separation of a control's UI and a control's logic. This enables
binding from within the template definition to the templated parent (the run time object
instance where the template is applied). For this case, the TemplateBinding Markup
Extension is in fact a shorthand for the following binding expression: {Binding
RelativeSource={RelativeSource TemplatedParent}} . TemplateBinding or
{RelativeSource TemplatedParent} usages are both only relevant within the XAML that
elements that are part of control composition in a template can use FindAncestor
bindings to the parent elements in that same composition structure.
In the object element syntax for FindAncestor mode shown in the XAML Syntax
sections, the second object element syntax is used specifically for FindAncestor mode.
FindAncestor mode requires an AncestorType value. You must set AncestorType as an
attribute using an x:Type Markup Extension reference to the type of ancestor to look for.
The AncestorType value is used when the binding request is processed at run-time.
For FindAncestor mode, the optional property AncestorLevel can help disambiguate the
ancestor lookup in cases where there is possibly more than one ancestor of that type
existing in the element tree.
For more information on how to use the FindAncestor mode, see RelativeSource.
{RelativeSource Self} is useful for scenarios where one property of an instance should
depend on the value of another property of the same instance, and no general
dependency property relationship (such as coercion) already exists between those two
properties. Although it is rare that two properties exist on an object such that the values
are literally identical (and are identically typed), you can also apply a Converter
parameter to a binding that has {RelativeSource Self} , and use the converter to
convert between source and target types. Another scenario for {RelativeSource Self} is
as part of a MultiDataTrigger.
For example, the following XAML defines a Rectangle element such that no matter what
value is entered for Width, the Rectangle is always a square: <Rectangle Width="200"
Height="{Binding RelativeSource={RelativeSource Self}, Path=Width}" .../>
In the following example, the first TextBlock in the items template displays the current
number. The second TextBlock binding is a MultiBinding that nominally has two Binding
constituents: the current record, and a binding that deliberately uses the previous data
record by using {RelativeSource PreviousData} . Then, a converter on the MultiBinding
calculates the difference and returns it to the binding.
XML
<ListBox Name="fibolist">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}"/>
<TextBlock>, difference = </TextBlock>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource
DiffConverter}">
<Binding/>
<Binding RelativeSource="{RelativeSource
PreviousData}"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Describing data binding as a concept is not covered here, see Data Binding Overview.
In the WPF XAML processor implementation, the handling for this markup extension is
defined by the RelativeSource class.
when there is a requirement to escape attribute values to be other than literal values or
handler names, and the requirement is more global than just putting type converters on
certain types or properties. All markup extensions in XAML use the { and } characters
in their attribute syntax, which is the convention by which a XAML processor recognizes
that a markup extension must process the attribute. For more information, see Markup
Extensions and WPF XAML.
See also
Binding
Styling and Templating
XAML in WPF
Markup Extensions and WPF XAML
Data Binding Overview
Binding Declarations Overview
x:Type Markup Extension
StaticResource Markup Extension
Article • 02/06/2023
<object>
<object.property>
<StaticResource ResourceKey="key" ... />
</object.property>
</object>
XAML Values
Value Description
key The key for the requested resource. This key was initially assigned by the x:Key Directive if
a resource was created in markup, or was provided as the key parameter when calling
ResourceDictionary.Add if the resource was created in code.
Remarks
) Important
A StaticResource must not attempt to make a forward reference to a resource that
is defined lexically further within the XAML file. Attempting to do so is not
supported, and even if such a reference does not fail, attempting the forward
reference will incur a load time performance penalty when the internal hash tables
representing a ResourceDictionary are searched. For best results, adjust the
composition of your resource dictionaries such that forward references can be
avoided. If you cannot avoid a forward reference, use DynamicResource Markup
Extension instead.
A resource key can be any string defined in the XamlName Grammar. A resource key can
also be other object types, such as a Type. A Type key is fundamental to how controls
can be styled by themes, through an implicit style key. For more information, see
Control Authoring Overview.
Attribute syntax is the most common syntax used with this markup extension. The string
token provided after the StaticResource identifier string is assigned as the ResourceKey
value of the underlying StaticResourceExtension extension class.
StaticResource can be used in object element syntax. In this case, specifying the value
StaticResource can also be used in a verbose attribute usage that specifies the
XML
The verbose usage is often useful for extensions that have more than one settable
property, or if some properties are optional. Because StaticResource has only one
settable property, which is required, this verbose usage is not typical.
In the WPF XAML processor implementation, the handling for this markup extension is
defined by the StaticResourceExtension class.
when there is a requirement to escape attribute values to be other than literal values or
handler names, and the requirement is more global than just putting type converters on
certain types or properties. All markup extensions in XAML use the { and } characters in
their attribute syntax, which is the convention by which a XAML processor recognizes
that a markup extension must process the attribute. For more information, see Markup
Extensions and WPF XAML.
See also
Styling and Templating
XAML in WPF
Markup Extensions and WPF XAML
XAML Resources
Resources and Code
TemplateBinding Markup Extension
Article • 02/06/2023
Links the value of a property in a control template to be the value of another property
on the templated control.
XAML Values
Value Description
sourceProperty Another dependency property that exists on the type being templated,
specified by its DependencyProperty.Name.
- or -
Remarks
A TemplateBinding is an optimized form of a Binding for template scenarios, analogous
to a Binding constructed with {Binding RelativeSource={RelativeSource
TemplatedParent}, Mode=OneWay} . A TemplateBinding is always a one-way binding, even if
Describing control templates as a concept is not covered here; for more information, see
Control Styles and Templates.
Attribute syntax is the most common syntax used with this markup extension. The string
token provided after the TemplateBinding identifier string is assigned as the Property
value of the underlying TemplateBindingExtension extension class.
Object element syntax is possible, but it is not shown because it has no realistic
application. TemplateBinding is used to fill values within setters, using evaluated
expressions, and using object element syntax for TemplateBinding to fill
<Setter.Property> property element syntax is unnecessarily verbose.
TemplateBinding can also be used in a verbose attribute usage that specifies the
XML
The verbose usage is often useful for extensions that have more than one settable
property, or if some properties are optional. Because TemplateBinding has only one
settable property, which is required, this verbose usage is not typical.
In the WPF XAML processor implementation, the handling for this markup extension is
defined by the TemplateBindingExtension class.
when there is a requirement to escape attribute values to be other than literal values or
handler names, and the requirement is more global than just putting type converters on
certain types or properties. All markup extensions in XAML use the { and } characters
in their attribute syntax, which is the convention by which a XAML processor recognizes
that a markup extension must process the attribute. For more information, see Markup
Extensions and WPF XAML.
See also
Style
ControlTemplate
Styling and Templating
XAML in WPF
Markup Extensions and WPF XAML
RelativeSource MarkupExtension
Binding Markup Extension
ThemeDictionary Markup Extension
Article • 02/06/2023
Provides a way for custom control authors or applications that integrate third-party
controls to load theme-specific resource dictionaries to use in styling the control.
<object>
<object.property>
<ThemeDictionary AssemblyName="assemblyUri"/>
<object.property>
<object>
XAML Values
Value Description
assemblyUri The uniform resource identifier (URI) of the assembly that contains theme
information. Typically, this is a pack URI that references an assembly in the larger
package. Assembly resources and pack URIs simplify deployment issues. For more
information see Pack URIs in WPF.
Remarks
This extension is intended to fill only one specific property value: a value for
ResourceDictionary.Source.
By using this extension, you can specify a single resources-only assembly that contains
some styles to use only when the Windows Aero theme is applied to the user's system,
other styles only when the Luna theme is active, and so on. By using this extension, the
contents of a control-specific resource dictionary can be automatically invalidated and
reloaded to be specific for another theme when required.
The assemblyUri string (AssemblyName property value) forms the basis of a naming
convention that identifies which dictionary applies for a particular theme. The
ProvideValue logic for ThemeDictionary completes the convention by generating a
uniform resource identifier (URI) that points to a particular theme dictionary variant, as
contained within a precompiled resource assembly. Describing this convention, or
theme interactions with general control styling and page/application level styling as a
concept, is not covered fully here. The basic scenario for using ThemeDictionary is to
specify the Source property of a ResourceDictionary declared at the application level.
When you provide a URI for the assembly through a ThemeDictionary extension rather
than as a direct URI, the extension logic will provide invalidation logic that applies
whenever the system theme changes.
Attribute syntax is the most common syntax used with this markup extension. The string
token provided after the ThemeDictionary identifier string is assigned as the
AssemblyName value of the underlying ThemeDictionaryExtension extension class.
ThemeDictionary may also be used in object element syntax. In this case, specifying the
value of the AssemblyName property is required.
ThemeDictionary can also be used in a verbose attribute usage that specifies the
Member property as a property=value pair:
XML
The verbose usage is often useful for extensions that have more than one settable
property, or if some properties are optional. Because ThemeDictionary has only one
settable property, which is required, this verbose usage is not typical.
In the WPF XAML processor implementation, the handling for this markup extension is
defined by the ThemeDictionaryExtension class.
See also
Styling and Templating
XAML in WPF
Markup Extensions and WPF XAML
WPF Application Resource, Content, and Data Files
PropertyPath XAML Syntax
Article • 08/18/2022
The PropertyPath object supports a complex inline XAML syntax for setting various
properties that take the PropertyPath type as their value. This topic documents the
PropertyPath syntax as applied to binding and animation syntaxes.
Primarily, WPF uses PropertyPath to describe object-model paths for traversing the
properties of an object data source, and to describe the target path for targeted
animations.
Some style and template properties such as Setter.Property take a qualified property
name that superficially resembles a PropertyPath. But this is not a true PropertyPath;
instead it is a qualified owner.property string format usage that is enabled by the WPF
XAML processor in combination with the type converter for DependencyProperty.
Note that data binding to XML does not use PropertyPath, because it does not use Path
in the Binding. Instead, you use XPath and specify valid XPath syntax into the XML
Document Object Model (DOM) of the data. XPath is also specified as a string, but is not
documented here; see Bind to XML Data Using an XMLDataProvider and XPath Queries.
A key to understanding property paths in data binding is that you can target the
binding to an individual property value, or you can instead bind to target properties that
take lists or collections. If you are binding collections, for instance binding a ListBox that
will expand depending on how many data items are in the collection, then your property
path should reference the collection object, not individual collection items. The data
binding engine will match the collection used as the data source to the type of the
binding target automatically, resulting in behavior such as populating a ListBox with an
items array.
key must be either the typed index to a dictionary or hash table, or the integer index of
an array. Also, the value of the key must be a type that is directly bindable to the
property where it is applied. For instance, a hash table that contains string keys and
string values can be used this way to bind to Text for a TextBox. Or, if the key points to a
collection or subindex, you could use this syntax to bind to a target collection property.
Otherwise, you need to reference a specific property, through a syntax such as <Binding
Path="[key].propertyName" .../> .
You can specify the type of the index if necessary. For details on this aspect of an
indexed property path, see Binding.Path.
The path properties propertyName and propertyName2 can be any properties that exist in
a relationship, where propertyName2 is a property that exists on the type that is the value
of propertyName .
usually only necessary for custom types or types otherwise outside that namespace.
propertyName must resolve to be the name of a property existing on the ownerType . This
The path is specified in XAML that is in a style or template that does not have a
specified Target Type. A qualified usage is generally not valid for cases other than
this, because in non-style, non-template cases, the property exists on an instance,
not a type.
The / in this syntax is used to navigate within a hierarchical data source object, and
multiple steps into the hierarchy with successive / characters are supported. The source
traversal accounts for the current record pointer position, which is determined by
synchronizing the data with the UI of its view. For details on binding with hierarchical
data source objects, and the concept of current record pointer in data binding, see Use
the Master-Detail Pattern with Hierarchical Data or Data Binding Overview.
7 Note
Superficially, this syntax resembles XPath. A true XPath expression for binding to an
XML data source is not used as a Path value and should instead be used for the
mutually exclusive XPath property.
Collection Views
To reference a named collection view, prefix the collection view name with the hash
character ( # ).
Multiple Indexers
XAML
or
XAML
If a given object supports multiple indexers, those indexers can be specified in order,
similar to an array referencing syntax. The object in question can be either the current
context or the value of a property that contains a multiple index object.
By default, the indexer values are typed by using the characteristics of the underlying
object. You can specify the type of the index if necessary. For details on typing the
indexers, see Binding.Path.
Mixing Syntaxes
Each of the syntaxes shown above can be interspersed. For instance, the following is an
example that creates a property path to the color at a particular x,y of a ColorGrid
property that contains a pixel grid array of SolidColorBrush objects:
XML
Inside indexers ([ ]), the caret character (^) escapes the next character.
You must escape (using XML entities) certain characters that are special to the XML
language definition. Use & to escape the character "&". Use > to escape the end
tag ">".
You must escape (using backslash \ ) characters that are special to the WPF XAML
parser behavior for processing a markup extension.
7 Note
Technically, these escapes work for a storyboard property path also, but you are
usually traversing object models for existing WPF objects, and escaping should be
unnecessary.
PropertyPath for Animation Targets
The target property of an animation must be a dependency property that takes either a
Freezable or a primitive type. However, the targeted property on a type and the
eventual animated property can exist on different objects. For animations, a property
path is used to define the connection between the named animation target object's
property and the intended target animation property, by traversing object-property
relationships in the property values.
The value type or the property being animated must be either a Freezable type or a
primitive. The property that starts the path must resolve to be the name of a
dependency property that exists on the specified TargetName type.
In order to support cloning for animating a Freezable that is already frozen, the object
specified by TargetName must be a FrameworkElement or FrameworkContentElement
derived class.
propertyName must resolve to be the name of a dependency property that exists on the
specified TargetName type.
Attached Properties
XML
dependency properties, so this issue is only of concern for custom attached properties.)
Indexers
XML
<animation
Storyboard.TargetProperty="propertyName.propertyName2[index].propertyName3"
... />
Most dependency properties or Freezable types do not support an indexer. Therefore,
the only usage for an indexer in an animation path is at an intermediate position
between the property that starts the chain on the named target and the eventual
animated property. In the provided syntax, that is propertyName2 . For instance, an
indexer usage might be necessary if the intermediate property is a collection such as
TransformGroup, in a property path such as RenderTransform.Children[1].Angle .
PropertyPath in Code
Code usage for PropertyPath, including how to construct a PropertyPath, is documented
in the reference topic for PropertyPath.
In general, PropertyPath is designed to use two different constructors, one for the
binding usages and simplest animation usages, and one for the complex animation
usages. Use the PropertyPath(Object) signature for binding usages, where the object is a
string. Use the PropertyPath(Object) signature for one-step animation paths, where the
object is a DependencyProperty. Use the PropertyPath(String, Object[]) signature for
complex animations. This latter constructor uses a token string for the first parameter
and an array of objects that fill positions in the token string to define a property path
relationship.
See also
PropertyPath
Data Binding Overview
Storyboards Overview
PresentationOptions:Freeze Attribute
Article • 08/10/2023
Sets the IsFrozen state to true on the containing Freezable element. Default behavior
for a Freezable without the PresentationOptions:Freeze attribute specified is that
IsFrozen is false at load time, and dependent on general Freezable behavior at runtime.
<object
xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/pres
entation/options"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="PresentationOptions">
<freezableElement PresentationOptions:Freeze="true"/>
</object>
XAML Values
Value Description
PresentationOptions An XML namespace prefix, which can be any valid prefix string, per the
XML 1.0 specification. The prefix PresentationOptions is used for
identification purposes in this documentation.
Remarks
The Freeze attribute is the only attribute or other programming element defined in the
http://schemas.microsoft.com/winfx/2006/xaml/presentation/options XML namespace.
The Freeze attribute exists in this special namespace specifically so that it can be
designated as ignorable, using mc:Ignorable Attribute as part of the root element
declarations. The reason that Freeze must be able to be ignorable is because not all
XAML processor implementations are able to freeze a Freezable at load time; this
capability is not part of the XAML specification.
The ability to process the Freeze attribute is specifically built in to the XAML processor
that processes XAML for compiled applications. The attribute is not supported by any
class, and the attribute syntax is not extensible or modifiable. If you are implementing
your own XAML processor you can choose to parallel the freezing behavior of the WPF
XAML processor when processing the Freeze attribute on Freezable elements at load
time.
Any value for the Freeze attribute other than true (not case sensitive) generates a load
time error. (Specifying the Freeze attribute as false is not an error, but that is already
the default, so setting to false does nothing).
See also
Freezable
Freezable Objects Overview
mc:Ignorable Attribute
Markup Compatibility (mc:) Language
Features
Article • 02/06/2023
In This Section
mc:Ignorable Attribute
mc:ProcessContent Attribute
mc:Ignorable Attribute
Article • 02/06/2023
Specifies which XML namespace prefixes encountered in a markup file may be ignored
by a XAML processor. The mc:Ignorable attribute supports markup compatibility both
for custom namespace mapping and for XAML versioning.
<object
xmlns:ignorablePrefix="ignorableUri"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="ignorablePrefix"...>
<ignorablePrefix1:ThisElementCanBeIgnored/>
</object>
<object
xmlns:ignorablePrefix1="ignorableUri"
xmlns:ignorablePrefix2="ignorableUri2"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="ignorablePrefix1 ignorablePrefix2"...>
<ignorablePrefix1:ThisElementCanBeIgnored/>
</object>
XAML Values
Value Description
ignorablePrefix, Any valid prefix string, per the XML 1.0 specification.
ignorablePrefix1, etc.
ignorableUri Any valid URI for designating a namespace, per the XML 1.0
specification.
Value Description
Remarks
The mc XML namespace prefix is the recommended prefix convention to use when
mapping the XAML compatibility namespace
http://schemas.openxmlformats.org/markup-compatibility/2006 .
Elements or attributes where the prefix portion of the element name are identified as
mc:Ignorable will not raise errors when processed by a XAML processor. If that attribute
could not be resolved to an underlying type or programming construct, then that
element is ignored. Note however that ignored elements might still generate additional
parsing errors for additional element requirements that are side effects of that element
not being processed. For instance, a particular element content model might require
exactly one child element, but if the specified child element was in an mc:Ignorable
prefix, and the specified child element could not be resolved to a type, then the XAML
processor might raise an error.
does not apply to namespace mappings into assemblies, which specify a CLR
namespace and an assembly (or default to the current executable as the assembly).
If you are implementing a XAML processor, your processor implementation must not
raise parsing or processing errors on type resolution for any element or attribute that is
qualified by a prefix that is identified as mc:Ignorable . But your processor
implementation can still raise exceptions that are a secondary result of an element
failing to load or be processed, such as the one-child element example given earlier.
By default, a XAML processor will ignore content within an ignored element. However,
you can specify an additional attribute, mc:ProcessContent Attribute, to require
continued processing of content within an ignored element by the next available parent
element.
Multiple prefixes can be specified in the attribute, using one or more white-space
characters as the separator, for example: mc:Ignorable="ignore1 ignore2" .
See also
XamlReader
PresentationOptions:Freeze Attribute
XAML in WPF
Documents in WPF
mc:ProcessContent Attribute
Article • 03/17/2022
Specifies which XAML elements should still have content processed by relevant parent
elements, even if the immediate parent element may be ignored by a XAML processor
due to specifying mc:Ignorable Attribute. The mc:ProcessContent attribute supports
markup compatibility both for custom namespace mapping and for XAML versioning.
<object
xmlns:ignorablePrefix="ignorableUri"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="ignorablePrefix"...
mc:ProcessContent="ignorablePrefix:ThisElementCanBeIgnored"
>
<ignorablePrefix:ThisElementCanBeIgnored>
[content]
</ignorablePrefix:ThisElementCanBeIgnored>
</object>
XAML Values
Value Description
ignorablePrefix Any valid prefix string, per the XML 1.0 specification.
ignorableUri Any valid URI for designating a namespace, per the XML 1.0
specification.
Remarks
By default, a XAML processor will ignore content within an ignored element. You can
specify a specific element by mc:ProcessContent , and a XAML processor will continue to
process the content within the ignored element. This would typically be used if the
content is nested within several tags, at least one of which is ignorable and at least one
of which is not ignorable.
Multiple prefixes may be specified in the attribute, using a space separator, for example:
mc:ProcessContent="ignore:Element1 ignore:Element2" .
See also
mc:Ignorable Attribute
XAML in WPF
Base Elements
Article • 02/06/2023
In This Section
Base Elements Overview
Freezable Objects Overview
Alignment, Margins, and Padding Overview
How-to Topics
Reference
UIElement
ContentElement
FrameworkElement
FrameworkContentElement
Related Sections
WPF Architecture
XAML in WPF
Element Tree and Serialization
Properties
Events
Input
Resources
Styling and Templating
Threading Model
Base Elements Overview
Article • 02/06/2023
If you are implementing a control, which is really one of the more common reasons for
deriving from a WPF class, you probably want to derive from a class that is a practical
control, a control family base class, or at least from the Control base class. For some
guidance and practical examples, see Control Authoring Overview.
If you are not creating a control and need to derive from a class that is higher in the
hierarchy, the following sections are intended as a guide for what characteristics are
defined in each base element class.
If you create a class that derives from DependencyObject, you inherit the following
functionality:
If you create a class that derives from UIElement, you inherit the following functionality
in addition to that provided by DependencyObject:
Basic support for animated property values. For more information, see Animation
Overview.
Basic input event support, and commanding support. For more information, see
Input Overview and Commanding Overview.
Support for styling and storyboards. For more information, see Style and
Storyboards Overview.
Support for data binding. For more information, see Data Binding Overview.
Support for dynamic resource references. For more information, see XAML
Resources.
Property value inheritance support, and other flags in the metadata that help
report conditions about properties to framework services such as data binding,
styles, or the framework implementation of layout. For more information, see
Framework Property Metadata.
The concept of the logical tree. For more information, see Trees in WPF.
If you create a class that derives from ContentElement, you inherit the following
functionality in addition to that provided by DependencyObject:
Basic input event support, and commanding support. For more information, see
Input Overview and Commanding Overview.
If you create a class that derives from FrameworkContentElement, you get the following
functionality in addition to that provided by ContentElement:
Support for styling and storyboards. For more information, see Style and
Animation Overview.
Support for data binding. For more information, see Data Binding Overview.
Support for dynamic resource references. For more information, see XAML
Resources.
Property value inheritance support, and other flags in the metadata that help
report conditions about properties to framework services like data binding, styles,
or the framework implementation of layout. For more information, see Framework
Property Metadata.
You do not inherit access to layout system modifications (such as
ArrangeOverride). Layout system implementations are only available on
FrameworkElement. However, you inherit an OnPropertyChanged override that can
detect changes to properties that influence layout and report these to any content
hosts.
Content models are documented for a variety of classes. The content model for a class is
one possible factor you should consider if you want to find an appropriate class to
derive from. For more information, see WPF Content Model.
DispatcherObject
DispatcherObject provides support for the WPF threading model and enables all objects
created for WPF applications to be associated with a Dispatcher. Even if you do not
derive from UIElement, DependencyObject, or Visual, you should consider deriving from
DispatcherObject in order to get this threading model support. For more information,
see Threading Model.
Visual
Visual implements the concept of a 2D object that generally requires visual presentation
in a roughly rectangular region. The actual rendering of a Visual happens in other
classes (it is not self-contained), but the Visual class provides a known type that is used
by rendering processes at various levels. Visual implements hit testing, but it does not
expose events that report hit-testing positives (these are in UIElement). For more
information, see Visual Layer Programming.
Freezable
Freezable simulates immutability in a mutable object by providing the means to
generate copies of the object when an immutable object is required or desired for
performance reasons. The Freezable type provides a common basis for certain graphics
elements such as geometries and brushes, as well as animations. Notably, a Freezable is
not a Visual; it can hold properties that become subproperties when the Freezable is
applied to fill a property value of another object, and those subproperties might affect
rendering. For more information, see Freezable Objects Overview.
Animatable
Animatable is a Freezable derived class that specifically adds the animation control layer
and some utility members so that currently animated properties can be distinguished
from nonanimated properties.
Control
Control is the intended base class for the type of object that is variously termed a
control or component, depending on the technology. In general, WPF control classes
are classes that either directly represent a UI control or participate closely in control
composition. The primary functionality that Control enables is control templating.
See also
Control
Dependency Properties Overview
Control Authoring Overview
WPF Architecture
Freezable Objects Overview
Article • 08/04/2022
This topic describes how to effectively use and create Freezable objects, which provide
special features that can help improve application performance. Examples of freezable
objects include brushes, pens, transformations, geometries, and animations.
What Is a Freezable?
A Freezable is a special type of object that has two states: unfrozen and frozen. When
unfrozen, a Freezable appears to behave like any other object. When frozen, a Freezable
can no longer be modified.
Although the Freezable class has many applications, most Freezable objects in Windows
Presentation Foundation (WPF) are related to the graphics sub-system.
The Freezable class makes it easier to use certain graphics system objects and can help
improve application performance. Examples of types that inherit from Freezable include
the Brush, Transform, and Geometry classes. Because they contain unmanaged
resources, the system must monitor these objects for modifications, and then update
their corresponding unmanaged resources when there is a change to the original object.
Even if you don't actually modify a graphics system object, the system must still spend
some of its resources monitoring the object, in case you do change it.
For example, suppose you create a SolidColorBrush brush and use it to paint the
background of a button.
C#
When the button is rendered, the WPF graphics sub-system uses the information you
provided to paint a group of pixels to create the appearance of a button. Although you
used a solid color brush to describe how the button should be painted, your solid color
brush doesn't actually do the painting. The graphics system generates fast, low-level
objects for the button and the brush, and it is those objects that actually appear on the
screen.
If you were to modify the brush, those low-level objects would have to be regenerated.
The freezable class is what gives a brush the ability to find its corresponding generated,
low-level objects and to update them when it changes. When this ability is enabled, the
brush is said to be "unfrozen."
A freezable's Freeze method enables you to disable this self-updating ability. You can
use this method to make the brush become "frozen," or unmodifiable.
7 Note
C#
if (myBrush.CanFreeze)
{
// Makes the brush unmodifiable.
myBrush.Freeze();
}
7 Note
For convenience, freezable objects remain unfrozen unless you explicitly freeze
them.
Using Freezables
Using an unfrozen freezable is like using any other type of object. In the following
example, the color of a SolidColorBrush is changed from yellow to red after it's used to
paint the background of a button. The graphics system works behind the scenes to
automatically change the button from yellow to red the next time the screen is
refreshed.
C#
Freezing a Freezable
To make a Freezable unmodifiable, you call its Freeze method. When you freeze an
object that contains freezable objects, those objects are frozen as well. For example, if
you freeze a PathGeometry, the figures and segments it contains would be frozen too.
It has properties set by a dynamic resource. (See the XAML Resources for more
information about dynamic resources.)
If these conditions are false, and you don't intend to modify the Freezable, then you
should freeze it to gain the performance benefits described earlier.
Once you call a freezable's Freeze method, it can no longer be modified. Attempting to
modify a frozen object causes an InvalidOperationException to be thrown. The following
code throws an exception, because we attempt to modify the brush after it's been
frozen.
C#
if (myBrush.CanFreeze)
{
// Makes the brush unmodifiable.
myBrush.Freeze();
}
myButton.Background = myBrush;
try {
To avoid throwing this exception, you can use the IsFrozen method to determine
whether a Freezable is frozen.
C#
if (myBrush.CanFreeze)
{
// Makes the brush unmodifiable.
myBrush.Freeze();
}
myButton.Background = myBrush;
In the preceding code example, a modifiable copy was made of a frozen object using
the Clone method. The next section discusses cloning in more detail.
7 Note
Because a frozen freezable cannot be animated, the animation system will
automatically create modifiable clones of frozen Freezable objects when you try to
animate them with a Storyboard. To eliminate the performance overhead caused
by cloning, leave an object unfrozen if you intend to animate it. For more
information about animating with storyboards, see the Storyboards Overview.
declared as a page resource and frozen. It is then used to set the background of a
button.
XAML
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/pres
entation/options"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="PresentationOptions">
<Page.Resources>
<StackPanel>
</StackPanel>
</Page>
To use the Freeze attribute, you must map to the presentation options namespace:
http://schemas.microsoft.com/winfx/2006/xaml/presentation/options .
xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/pres
entation/options"
Because not all XAML readers recognize this attribute, it's recommended that you use
the mc:Ignorable Attribute to mark the Presentation:Freeze attribute as ignorable:
XAML
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="PresentationOptions"
"Unfreezing" a Freezable
Once frozen, a Freezable can never be modified or unfrozen; however, you can create an
unfrozen clone using the Clone or CloneCurrentValue method.
In the following example, the button's background is set with a brush and that brush is
then frozen. An unfrozen copy is made of the brush using the Clone method. The clone
is modified and used to change the button's background from yellow to red.
C#
myButton.Background = myBrush;
7 Note
Regardless of which clone method you use, animations are never copied to the new
Freezable.
The Clone and CloneCurrentValue methods produce deep copies of the freezable. If the
freezable contains other frozen freezable objects, they are also cloned and made
modifiable. For example, if you clone a frozen PathGeometry to make it modifiable, the
figures and segments it contains are also copied and made modifiable.
Easy cloning: the Freezable class has already implemented several methods that
produce deep clones.
Every Freezable subclass must override the CreateInstanceCore method. If your class
uses dependency properties for all its data, you're finished.
If your class contains non-dependency property data members, you must also override
the following methods:
CloneCore
CloneCurrentValueCore
GetAsFrozenCore
GetCurrentValueAsFrozenCore
FreezeCore
You must also observe the following rules for accessing and writing to data members
that are not dependency properties:
At the beginning of any API that reads non-dependency property data members,
call the ReadPreamble method.
At the beginning of any API that writes non-dependency property data members,
call the WritePreamble method. (Once you've called WritePreamble in an API, you
don't need to make an additional call to ReadPreamble if you also read non-
dependency property data members.)
Call the WritePostscript method before exiting methods that write to non-
dependency property data members.
7 Note
It's very important that you begin each Freezable method you override with a call
to the base implementation.
For an example of a custom Freezable class, see the Custom Animation Sample .
See also
Freezable
Custom Animation Sample
Dependency Properties Overview
Custom Dependency Properties
Alignment, Margins, and Padding
Overview
Article • 03/17/2022
The FrameworkElement class exposes several properties that are used to precisely
position child elements. This topic discusses four of the most important properties:
HorizontalAlignment, Margin, Padding, and VerticalAlignment. The effects of these
properties are important to understand, because they provide the basis for controlling
the position of elements in Windows Presentation Foundation (WPF) applications.
The following illustration shows a layout scenario that utilizes several positioning
properties.
At first glance, the Button elements in this illustration may appear to be placed
randomly. However, their positions are actually precisely controlled by using a
combination of margins, alignments, and padding.
The following example describes how to create the layout in the preceding illustration. A
Border element encapsulates a parent StackPanel, with a Padding value of 15 device
independent pixels. This accounts for the narrow LightBlue band that surrounds the
child StackPanel. Child elements of the StackPanel are used to illustrate each of the
various positioning properties that are detailed in this topic. Three Button elements are
used to demonstrate both the Margin and HorizontalAlignment properties.
C#
// Create the application's main Window.
mainWindow = new Window ();
mainWindow.Title = "Margins, Padding and Alignment Sample";
// Add a Border
myBorder = new Border();
myBorder.Background = Brushes.LightBlue;
myBorder.BorderBrush = Brushes.Black;
myBorder.Padding = new Thickness(15);
myBorder.BorderThickness = new Thickness(2);
The following diagram provides a close-up view of the various positioning properties
that are used in the preceding sample. Subsequent sections in this topic describe in
greater detail how to use each positioning property.
Understanding Alignment Properties
The HorizontalAlignment and VerticalAlignment properties describe how a child element
should be positioned within a parent element's allocated layout space. By using these
properties together, you can position child elements precisely. For example, child
elements of a DockPanel can specify four different horizontal alignments: Left, Right, or
Center, or to Stretch to fill available space. Similar values are available for vertical
positioning.
7 Note
Explicitly-set Height and Width properties on an element take precedence over the
Stretch property value. Attempting to set Height, Width, and a
HorizontalAlignment value of Stretch results in the Stretch request being
ignored.
HorizontalAlignment Property
The HorizontalAlignment property declares the horizontal alignment characteristics to
apply to child elements. The following table shows each of the possible values of the
HorizontalAlignment property.
Member Description
Left Child elements are aligned to the left of the parent element's allocated layout space.
Member Description
Center Child elements are aligned to the center of the parent element's allocated layout
space.
Right Child elements are aligned to the right of the parent element's allocated layout space.
Stretch Child elements are stretched to fill the parent element's allocated layout space.
(Default) Explicit Width and Height values take precedence.
The following example shows how to apply the HorizontalAlignment property to Button
elements. Each attribute value is shown, to better illustrate the various rendering
behaviors.
C#
The preceding code yields a layout similar to the following image. The positioning
effects of each HorizontalAlignment value are visible in the illustration.
VerticalAlignment Property
The VerticalAlignment property describes the vertical alignment characteristics to apply
to child elements. The following table shows each of the possible values for the
VerticalAlignment property.
Member Description
Top Child elements are aligned to the top of the parent element's allocated layout space.
Center Child elements are aligned to the center of the parent element's allocated layout
space.
Bottom Child elements are aligned to the bottom of the parent element's allocated layout
space.
Stretch Child elements are stretched to fill the parent element's allocated layout space.
(Default) Explicit Width and Height values take precedence.
The following example shows how to apply the VerticalAlignment property to Button
elements. Each attribute value is shown, to better illustrate the various rendering
behaviors. For purposes of this sample, a Grid element with visible gridlines is used as
the parent, to better illustrate the layout behavior of each property value.
C#
XAML
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowTitle="VerticalAlignment Sample">
<Border Background="LightBlue" BorderBrush="Black" BorderThickness="2"
Padding="15">
<Grid Background="White" ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" FontSize="18"
HorizontalAlignment="Center">VerticalAlignment Sample</TextBlock>
<Button Grid.Row="1" Grid.Column="0"
VerticalAlignment="Top">Button 1 (Top)</Button>
<Button Grid.Row="2" Grid.Column="0"
VerticalAlignment="Bottom">Button 2 (Bottom)</Button>
<Button Grid.Row="3" Grid.Column="0"
VerticalAlignment="Center">Button 3 (Center)</Button>
<Button Grid.Row="4" Grid.Column="0"
VerticalAlignment="Stretch">Button 4 (Stretch)</Button>
</Grid>
</Border>
</Page>
The preceding code yields a layout similar to the following image. The positioning
effects of each VerticalAlignment value are visible in the illustration.
element's rendering position and the rendering position of its neighbor elements and
children.
7 Note
The following example shows how to apply uniform margins around a group of Button
elements. The Button elements are spaced evenly with a ten-pixel margin buffer in each
direction.
C#
XAML
C#
XAML
The following example shows how to apply Padding to a parent Border element.
C#
XAML
<Border Background="LightBlue"
BorderBrush="Black"
BorderThickness="2"
CornerRadius="45"
Padding="25">
The following example demonstrates each of the concepts that are detailed in this topic.
Building on the infrastructure found in the first sample in this topic, this example adds a
Grid element as a child of the Border in the first sample. Padding is applied to the parent
Border element. The Grid is used to partition space between three child StackPanel
elements. Button elements are again used to show the various effects of Margin and
HorizontalAlignment. TextBlock elements are added to each ColumnDefinition to better
define the various properties applied to the Button elements in each column.
C#
XAML
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowTitle="Margins, Padding and Alignment Sample">
<Border Background="LightBlue"
BorderBrush="Black"
BorderThickness="2"
CornerRadius="45"
Padding="25">
<Grid Background="White" ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
When compiled, the preceding application yields a UI that looks like the following
illustration. The effects of the various property values are evident in the spacing between
elements, and significant property values for elements in each column are shown within
TextBlock elements.
What's Next
Positioning properties defined by the FrameworkElement class enable fine control of
element placement within WPF applications. You now have several techniques you can
use to better position elements using WPF.
Additional resources are available that explain WPF layout in greater detail. The Panels
Overview topic contains more detail about the various Panel elements. The topic
Walkthrough: My first WPF desktop application introduces advanced techniques that
use layout elements to position components and bind their actions to data sources.
See also
FrameworkElement
HorizontalAlignment
VerticalAlignment
Margin
Panels Overview
Layout
WPF Layout Gallery Sample
Base Elements How-to Topics
Article • 02/06/2023
The topics in this section describe how to use the four WPF base elements: UIElement,
ContentElement, FrameworkElement, and FrameworkContentElement.
In This Section
Make a UIElement Transparent or Semi-Transparent
Animate the Size of a FrameworkElement
Determine Whether a Freezable Is Frozen
Handle a Loaded Event
Set Margins of Elements and Controls
Make a Freezable Read-Only
Obtain a Writable Copy of a Read-Only Freezable
Flip a UIElement Horizontally or Vertically
Use a ThicknessConverter Object
Handle the ContextMenuOpening Event
Reference
UIElement
ContentElement
FrameworkElement
FrameworkContentElement
Related Sections
Base Elements
How to: Make a UIElement Transparent
or Semi-Transparent
Article • 02/06/2023
Example
The following example sets the Opacity of a button to 0.25 , making it and its contents
(in this case, the button's text) 25% opaque.
XAML
<!-- Both the button and its text are made 25% opaque. -->
<Button Opacity="0.25">A Button</Button>
C#
//
// Both the button and its text are made 25% opaque.
//
Button myTwentyFivePercentOpaqueButton = new Button();
myTwentyFivePercentOpaqueButton.Opacity = new Double();
myTwentyFivePercentOpaqueButton.Opacity = 0.25;
myTwentyFivePercentOpaqueButton.Content = "A Button";
If an element's contents have their own Opacity settings, those values are multiplied
against the containing elements Opacity.
The following example sets a button's Opacity to 0.25 , and the Opacity of an Image
control contained with in the button to 0.5 . As a result, the image appears 12.5%
opaque: 0.25 * 0.5 = 0.125.
XAML
C#
//
// The image contained within this button has an
// effective opacity of 0.125 (0.25*0.5 = 0.125);
//
Button myImageButton = new Button();
myImageButton.Opacity = new Double();
myImageButton.Opacity = 0.25;
Another way to control the opacity of an element is to set the opacity of the Brush that
paints the element. This approach enables you to selectively alter the opacity of portions
of an element, and provides performance benefits over using the element's Opacity
property. The following example sets the Opacity of a SolidColorBrush used to paint the
button's Background is set to 0.25 . As a result, the brush's background is 25% opaque,
but its contents (the button's text) remain 100% opaque.
XAML
<!-- This button's background is made 25% opaque, but its
text remains 100% opaque. -->
<Button>
<Button.Background>
<SolidColorBrush Color="Gray" Opacity="0.25" />
</Button.Background>
A Button
</Button>
C#
//
// This button's background is made 25% opaque,
// but its text remains 100% opaque.
//
Button myOpaqueTextButton = new Button();
SolidColorBrush mySolidColorBrush = new SolidColorBrush(Colors.Gray);
mySolidColorBrush.Opacity = 0.25;
myOpaqueTextButton.Background = mySolidColorBrush;
myOpaqueTextButton.Content = "A Button";
You may also control the opacity of individual colors within a brush. For more
information about colors and brushes, see Painting with Solid Colors and Gradients
Overview. For an example showing how to animate an element's opacity, see Animate
the Opacity of an Element or Brush.
How to: Animate the Size of a
FrameworkElement
Article • 02/06/2023
To animate the size of a FrameworkElement, you can either animate its Width and
Height properties or use an animated ScaleTransform.
In the following example animates the size of two buttons using these two approaches.
One button is resized by animating its Width property and another is resized by
animating a ScaleTransform applied to its RenderTransform property. Each button
contains some text. Initially, the text appears the same in both buttons, but as the
buttons are resized, the text in the second button becomes distorted.
Example
XAML
<!-- AnimatingSizeExample.xaml
This example shows two ways of animating the size
of a framework element. -->
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Microsoft.Samples.Animation.AnimatingSizeExample"
WindowTitle="Animating Size Example">
<Canvas Width="650" Height="400">
<Button Name="AnimatedWidthButton"
Canvas.Left="20" Canvas.Top="20"
Width="200" Height="150"
BorderBrush="Red" BorderThickness="5">
Click Me
<Button.Triggers>
<Button
Canvas.Left="20" Canvas.Top="200"
Width="200" Height="150"
BorderBrush="Black" BorderThickness="3">
Click Me
<Button.RenderTransform>
<ScaleTransform x:Name="MyAnimatedScaleTransform"
ScaleX="1" ScaleY="1" />
</Button.RenderTransform>
<Button.Triggers>
When you transform an element, the entire element and its contents are transformed.
When you directly alter the size of an element, as in the case of the first button, the
element's contents are not resized unless their size and position depend on the size of
their parent element.
For more information about animating properties, see the Animation Overview. For
more information about transforms, see the Transforms Overview.
How to: Determine Whether a Freezable
Is Frozen
Article • 02/06/2023
This example shows how to determine whether a Freezable object is frozen. If you try to
modify a frozen Freezable object, it throws an InvalidOperationException. To avoid
throwing this exception, use the IsFrozen property of the Freezable object to determine
whether it is frozen.
Example
The following example freezes a SolidColorBrush and then tests it by using the IsFrozen
property to determine whether it is frozen.
C#
if (myBrush.CanFreeze)
{
// Makes the brush unmodifiable.
myBrush.Freeze();
}
myButton.Background = myBrush;
For more information about Freezable objects, see the Freezable Objects Overview.
See also
Freezable
IsFrozen
Freezable Objects Overview
How-to Topics
How to: Handle a Loaded Event
Article • 02/06/2023
Example
The following example uses Extensible Application Markup Language (XAML) together
with a code-behind file.
XAML
<StackPanel
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.FELoaded"
Loaded="OnLoad"
Name="root"
>
</StackPanel>
C#
See also
FrameworkElement
Object Lifetime Events
Routed Events Overview
How-to Topics
How to: Set Margins of Elements and
Controls
Article • 08/10/2023
This example describes how to set the Margin property, by changing any existing
property value for the margin in code-behind. The Margin property is a property of the
FrameworkElement base element, and is thus inherited by a variety of controls and other
elements.
This example is written in Extensible Application Markup Language (XAML), with a code-
behind file that the XAML refers to. The code-behind is shown in both a C# and a
Microsoft Visual Basic version.
Example
XAML
C#
This example shows how to make a Freezable read-only by calling its Freeze method.
You cannot freeze a Freezable object if any one of the following conditions is true
about the object:
It has properties that are set by a dynamic resource. For more information about
dynamic resources, see the XAML Resources.
If these conditions are false for your Freezable object and you do not intend to modify
it, consider freezing it to gain performance benefits.
Example
The following example freezes a SolidColorBrush, which is a type of Freezable object.
C#
if (myBrush.CanFreeze)
{
// Makes the brush unmodifiable.
myBrush.Freeze();
}
myButton.Background = myBrush;
For more information about Freezable objects, see the Freezable Objects Overview.
See also
Freezable
CanFreeze
Freeze
Freezable Objects Overview
How-to Topics
How to: Obtain a Writable Copy of a
Read-Only Freezable
Article • 02/06/2023
This example shows how to use the Clone method to create a writable copy of a read-
only Freezable.
After a Freezable object is marked as read-only ("frozen"), you cannot modify it.
However, you can use the Clone method to create a modifiable clone of the frozen
object.
Example
The following example creates a modifiable clone of a frozen SolidColorBrush object.
C#
myButton.Background = myBrush;
For more information about Freezable objects, see the Freezable Objects Overview.
See also
Freezable
CloneCurrentValue
Freezable Objects Overview
How-to Topics
How to: Flip a UIElement Horizontally or
Vertically
Article • 02/06/2023
XAML
XAML
XAML
XAML
<Button Content="Flip me!" Padding="5"
RenderTransformOrigin="0.5,0.5">
<Button.RenderTransform>
<ScaleTransform ScaleY="-1" />
</Button.RenderTransform>
</Button>
See also
Transforms Overview
How to: Use a ThicknessConverter
Object
Article • 08/18/2022
Example
This example shows how to create an instance of ThicknessConverter and use it to
change the thickness of a border.
The example defines a custom method called changeThickness ; this method first
converts the contents of a ListBoxItem, as defined in a separate Extensible Application
Markup Language (XAML) file, to an instance of Thickness, and later converts the
content into a String. This method passes the ListBoxItem to a ThicknessConverter
object, which converts the Content of a ListBoxItem to an instance of Thickness. This
value is then passed back as the value of the BorderThickness property of the Border.
C#
See also
Thickness
ThicknessConverter
Border
How to: Change the Margin Property
How to: Convert a ListBoxItem to a new Data Type
Panels Overview
How to: Handle the
ContextMenuOpening Event
Article • 02/06/2023
Example
The general technique is to get the source of the event, which is the specific control that
was right-clicked, and get the ContextMenu property from it. You typically want to check
the Items collection to see what context menu items already exist in the menu, and then
add or remove appropriate new MenuItem items to or from the collection.
C#
void AddItemToCM(object sender, ContextMenuEventArgs e)
{
//check if Item4 is already there, this will probably run more than once
FrameworkElement fe = e.Source as FrameworkElement;
ContextMenu cm = fe.ContextMenu;
foreach (MenuItem mi in cm.Items)
{
if ((String)mi.Header == "Item4") return;
}
MenuItem mi4 = new MenuItem();
mi4.Header = "Item4";
fe.ContextMenu.Items.Add(mi4);
}
The following is the simple handler code for replacing a ContextMenu. The code
references a custom BuildMenu method, which is separated out because it is called by
more than one of the example handlers.
C#
C#
ContextMenu BuildMenu()
{
ContextMenu theMenu = new ContextMenu();
MenuItem mia = new MenuItem();
mia.Header = "Item1";
MenuItem mib = new MenuItem();
mib.Header = "Item2";
MenuItem mic = new MenuItem();
mic.Header = "Item3";
theMenu.Items.Add(mia);
theMenu.Items.Add(mib);
theMenu.Items.Add(mic);
return theMenu;
}
However, if you use this style of handler for ContextMenuOpening, you can potentially
expose a timing issue if the object where you are setting the ContextMenu does not
have a preexisting context menu. When a user right-clicks a control,
ContextMenuOpening is raised even if the existing ContextMenu is empty or null. But in
this case, whatever new ContextMenu you set on the source element arrives too late to
be displayed. Also, if the user happens to right-click a second time, this time your new
ContextMenu appears, the value is non null, and your handler will properly replace and
display the menu when the handler runs a second time. This suggests two possible
workarounds:
1. Insure that ContextMenuOpening handlers always run against controls that have at
least a placeholder ContextMenu available, which you intend to be replaced by the
handler code. In this case, you can still use the handler shown in the previous
example, but you typically want to assign a placeholder ContextMenu in the initial
markup:
XAML
<StackPanel>
<Rectangle Fill="Yellow" Width="200" Height="100"
ContextMenuOpening="HandlerForCMO">
<Rectangle.ContextMenu>
<ContextMenu>
<MenuItem>Initial menu; this will be replaced ...</MenuItem>
</ContextMenu>
</Rectangle.ContextMenu>
</Rectangle>
<TextBlock>Right-click the rectangle above, context menu gets
replaced</TextBlock>
</StackPanel>
2. Assume that the initial ContextMenu value might be null, based on some
preliminary logic. You could either check ContextMenu for null, or use a flag in
your code to check whether your handler has been run at least once. Because you
assume that the ContextMenu is about to be displayed, your handler then sets
Handled to true in the event data. To the ContextMenuService that is responsible
for context menu display, a true value for Handled in the event data represents a
request to cancel the display for the context menu / control combination that
raised the event.
Now that you have suppressed the potentially suspect context menu, the next step is to
supply a new one, then display it. Setting the new one is basically the same as the
previous handler: you build a new ContextMenu and set the control source's
FrameworkElement.ContextMenu property with it. The additional step is that you must
now force the display of the context menu, because you suppressed the first attempt. To
force the display, you set the Popup.IsOpen property to true within the handler. Be
careful when you do this, because opening the context menu in the handler raises the
ContextMenuOpening event again. If you reenter your handler, it becomes infinitely
recursive. This is why you always need to check for null or use a flag if you open a
context menu from within a ContextMenuOpening event handler.
C#
See also
ContextMenu
FrameworkElement.ContextMenu
Base Elements Overview
ContextMenu Overview
Element Tree and Serialization
Article • 02/06/2023
WPF programming elements often exist in some form of tree relationship to each other.
For instance, an application UI created in XAML can be conceptualized as an object tree.
The element tree can be further divided into two discrete yet sometimes parallel trees:
the logical tree and the visual tree. Serialization in WPF involves saving the state of these
two trees as well as application state and writing it to a file, potentially as XAML.
In This Section
Trees in WPF
Serialization Limitations of XamlWriter.Save
Initialization for Object Elements Not in an Object Tree
How-to Topics
Reference
System.Windows.Markup
LogicalTreeHelper
VisualTreeHelper
Related Sections
WPF Architecture
XAML in WPF
Base Elements
Properties
Events
Input
Resources
Styling and Templating
Threading Model
Trees in WPF
Article • 08/18/2022
In many technologies, elements and components are organized in a tree structure where
developers directly manipulate the object nodes in the tree to affect the rendering or
behavior of an application. Windows Presentation Foundation (WPF) also uses several
tree structure metaphors to define relationships between program elements. For the
most part WPF developers can create an application in code or define portions of the
application in XAML while thinking conceptually about the object tree metaphor, but
will be calling specific API or using specific markup to do so rather than some general
object tree manipulation API such as you might use in XML DOM. WPF exposes two
helper classes that provide a tree metaphor view, LogicalTreeHelper and
VisualTreeHelper. The terms visual tree and logical tree are also used in the WPF
documentation because these same trees are useful for understanding the behavior of
certain key WPF features. This topic defines what the visual tree and logical tree
represent, discusses how such trees relate to an overall object tree concept, and
introduces LogicalTreeHelper and VisualTreeHelpers.
Trees in WPF
The most complete tree structure in WPF is the object tree. If you define an application
page in WPF subsystems and affect choices you make in markup or code.
Even though you do not always manipulate either the logical tree or the visual tree
directly, understanding the concepts of how the trees interact is useful for
understanding WPF as a technology. Thinking of WPF as a tree metaphor of some kind
is also crucial to understanding how property inheritance and event routing work in
WPF.
7 Note
Because the object tree is more of a concept than an actual API, another way to
think of the concept is as an object graph. In practice, there are relationships
between objects at run time where the tree metaphor will break down.
Nevertheless, particularly with XAML-defined UI, the tree metaphor is relevant
enough that most WPF documentation will use the term object tree when
referencing this general concept.
The Logical Tree
In WPF, you add content to UI elements by setting properties of the objects that back
those elements. For example, you add items to a ListBox control by manipulating its
Items property. By doing this, you are placing items into the ItemCollection that is the
Items property value. Similarly, to add objects to a DockPanel, you manipulate its
Children property value. Here, you are adding objects to the UIElementCollection. For a
code example, see How to: Add an Element Dynamically.
In Extensible Application Markup Language (XAML), when you place list items in a
ListBox or controls or other UI elements in a DockPanel, you also use the Items and
Children properties, either explicitly or implicitly, as in the following example.
XAML
<DockPanel
Name="ParentElement"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<!--implicit: <DockPanel.Children>-->
<ListBox DockPanel.Dock="Top">
<!--implicit: <ListBox.Items>-->
<ListBoxItem>
<TextBlock>Dog</TextBlock>
</ListBoxItem>
<ListBoxItem>
<TextBlock>Cat</TextBlock>
</ListBoxItem>
<ListBoxItem>
<TextBlock>Fish</TextBlock>
</ListBoxItem>
<!--implicit: </ListBox.Items>-->
</ListBox>
<Button Height="20" Width="100" DockPanel.Dock="Top">Buy a Pet</Button>
<!--implicit: </DockPanel.Children>-->
</DockPanel>
If you were to process this XAML as XML under a document object model, and if you
had included the tags commented out as implicit (which would have been legal), then
the resulting XML DOM tree would have included elements for <ListBox.Items> and the
other implicit items. But XAML does not process that way when you read the markup
and write to objects, the resulting object graph does not literally include ListBox.Items .
It does however have a ListBox property named Items that contains a ItemCollection,
and that ItemCollection is initialized but empty when the ListBox XAML is processed.
Then, each child object element that exists as content for the ListBox is added to the
ItemCollection by parser calls to ItemCollection.Add . This example of processing XAML
into an object tree is so far seemingly an example where the created object tree is
basically the logical tree.
However, the logical tree is not the entire object graph that exists for your application UI
at run time, even with the XAML implicit syntax items factored out. The main reason for
this is visuals and templates. For example, consider the Button. The logical tree reports
the Button object and also its string Content . But there is more to this button in the run-
time object tree. In particular, the button only appears on screen the way it does
because a specific Button control template was applied. The visuals that come from an
applied template (such as the template-defined Border of dark gray around the visual
button) are not reported in the logical tree, even if you are looking at the logical tree
during run time (such as handling an input event from the visible UI and then reading
the logical tree). To find the template visuals, you would instead need to examine the
visual tree.
For more information about how XAML syntax maps to the created object graph, and
implicit syntax in XAML, see XAML Syntax In Detail or XAML in WPF.
In addition, both static and dynamic resource references are resolved by looking
upwards through the logical tree for Resources collections on the initial requesting
object, and then continuing up the logical tree and checking each FrameworkElement
(or FrameworkContentElement) for another Resources value that contains a
ResourceDictionary, possibly containing that key. The logical tree is used for resource
lookup when both the logical tree and the visual tree are present. For more information
on resource dictionaries and lookup, see XAML Resources.
Tree Traversal
The LogicalTreeHelper class provides the GetChildren, GetParent, and FindLogicalNode
methods for logical tree traversal. In most cases, you should not have to traverse the
logical tree of existing controls, because these controls almost always expose their
logical child elements as a dedicated collection property that supports collection access
such as Add , an indexer, and so on. Tree traversal is mainly a scenario that is used by
control authors who choose not to derive from intended control patterns such as
ItemsControl or Panel where collection properties are already defined, and who intend
to provide their own collection property support.
The visual tree also supports a helper class for visual tree traversal, VisualTreeHelper. The
visual tree is not exposed as conveniently through control-specific properties, so the
VisualTreeHelper class is the recommended way to traverse the visual tree if that is
necessary for your programming scenario. For more information, see WPF Graphics
Rendering Overview.
7 Note
However, resource lookup can also extend beyond the immediate logical tree. For
application markup, the resource lookup can then continue onward to application-level
resource dictionaries and then to theme support and system values that are referenced
as static properties or keys. Themes themselves can also reference system values outside
of the theme logical tree if the resource references are dynamic. For more information
on resource dictionaries and the lookup logic, see XAML Resources.
See also
Input Overview
WPF Graphics Rendering Overview
Routed Events Overview
Initialization for Object Elements Not in an Object Tree
WPF Architecture
Serialization Limitations of
XamlWriter.Save
Article • 02/06/2023
The API Save can be used to serialize the contents of a Windows Presentation
Foundation (WPF) application as a Extensible Application Markup Language (XAML) file.
However, there are some notable limitations in exactly what is serialized. These
limitations and some general considerations are documented in this topic.
Serialization is Self-Contained
The serialized output of Save is self-contained; everything that is serialized is contained
inside a XAML single page, with a single root element, and no external references other
than URIs. For instance, if your page referenced resources from application resources,
these will appear as if they were a component of the page being serialized.
were already dereferenced at the time that in-memory objects were created by the
application runtime, and the Save logic does not revisit the original XAML to restore
such references to the serialized output. This potentially freezes any databound or
resource obtained value to be the value last used by the run-time representation, with
only limited or indirect ability to distinguish such a value from any other value set
locally. Images are also serialized as object references to images as they exist in the
project, rather than as original source references, losing whatever filename or URI was
originally referenced. Even resources declared within the same page are seen serialized
into the point where they were referenced, rather than being preserved as a key of a
resource collection.
Vector or graphical output: The output of the rendered area can be used to
reproduce the same vector or graphics when reloaded.
Rich text and flow documents: Text and all element formatting and element
containment within it is preserved in the output. This can be useful for mechanisms
that approximate a clipboard functionality.
Preserving business object data: If you have stored data in custom elements, such
as XML data, so long as your business objects follow basic XAML rules such as
providing custom constructors and conversion for by-reference property values,
these business objects can be perpetuated through serialization.
Initialization for Object Elements Not in
an Object Tree
Article • 02/06/2023
The visual tree also participates in this process. Elements that are part of the visual tree
through the templates are also not fully instantiated until connected.
The consequences of this behavior are that certain operations that rely on the
completed visual characteristics of an element require additional steps. An example is if
you are attempting to get the visual characteristics of a class that was constructed but
not yet attached to a tree. For instance, if you want to call Render on a
RenderTargetBitmap and the visual you are passing is an element not connected to a
tree, that element is not visually complete until additional initialization steps are
completed.
Sample Code
The following example is sample code for a console application that uses rendering APIs
and XamlReader.Load(Stream) of a loose XAML file to illustrate the proper placement of
BeginInit and EndInit around other API calls that adjust properties that affect rendering.
The example illustrates the main function only. The functions Rasterize and Save (not
shown) are utility functions that take care of image processing and IO.
C#
[STAThread]
static void Main(string[] args)
{
UIElement e;
string file = Directory.GetCurrentDirectory() + "\\starting.xaml";
using (Stream stream = File.Open(file, FileMode.Open))
{
// loading files from current directory, project settings take care
of copying the file
ParserContext pc = new ParserContext();
pc.BaseUri = new Uri(file, UriKind.Absolute);
e = (UIElement)XamlReader.Load(stream, pc);
}
/*
* Render effect at normal dpi, indicator is the original RED
rectangle
*/
RenderTargetBitmap image1 = Rasterize(e, paperSize.Width,
paperSize.Height, 96, 96);
Save(image1, "render1.png");
// now render the altered version, with the element built up and
initialized
See also
Trees in WPF
WPF Graphics Rendering Overview
XAML in WPF
Element Tree and Serialization How-to
Topics
Article • 02/06/2023
The topics in this section describe how to use the WPF element tree.
In This Section
Find an Element by Its Name
Override the Logical Tree
Reference
LogicalTreeHelper
VisualTreeHelper
System.Windows.Markup
Related Sections
How to: Find an Element by Its Name
Article • 02/06/2023
This example describes how to use the FindName method to find an element by its
Name value.
Example
In this example, the method to find a particular element by its name is written as the
event handler of a button. stackPanel is the Name of the root FrameworkElement being
searched, and the example method then visually indicates the found element by casting
it as TextBlock and changing one of the TextBlock visible UI properties.
C#
Although it is not necessary in most cases, advanced control authors have the option to
override the logical tree.
Example
This example describes how to subclass StackPanel to override the logical tree, in this
case to enforce a behavior that the panel may only have and will only render a single
child element. This isn't necessarily a practically desirable behavior, but is shown here as
a means of illustrating the scenario for overriding an element's normal logical tree.
C#
public SingletonPanel()
{
}
Windows Presentation Foundation (WPF) provides a set of services that can be used to
extend the functionality of a common language runtime (CLR) property. Collectively,
these services are typically referred to as the WPF property system. A property that is
backed by the WPF property system is known as a dependency property.
In This Section
Dependency Properties Overview
Attached Properties Overview
Custom Dependency Properties
Dependency Property Metadata
Dependency Property Callbacks and Validation
Framework Property Metadata
Dependency Property Value Precedence
Read-Only Dependency Properties
Property Value Inheritance
Dependency Property Security
Safe Constructor Patterns for DependencyObjects
Collection-Type Dependency Properties
XAML Loading and Dependency Properties
How-to Topics
Reference
DependencyProperty
PropertyMetadata
FrameworkPropertyMetadata
DependencyObject
Related Sections
WPF Architecture
XAML in WPF
Base Elements
Element Tree and Serialization
Events
Input
Resources
WPF Content Model
Threading Model
Dependency properties overview
Article • 02/06/2023
Windows Presentation Foundation (WPF) provides a set of services that can be used to
extend the functionality of a type's property. Collectively, these services are typically
referred to as the WPF property system. A property that is backed by the WPF property
system is known as a dependency property. This overview describes the WPF property
system and the capabilities of a dependency property. This includes how to use existing
dependency properties in XAML and in code. This overview also introduces specialized
aspects of dependency properties, such as dependency property metadata, and how to
create your own dependency property in a custom class.
Prerequisites
This topic assumes that you have some basic knowledge of the .NET type system and
object-oriented programming. In order to follow the examples in this topic, you should
also understand XAML and know how to write WPF applications. For more information,
see Walkthrough: My first WPF desktop application.
The following lists the terminology that is used with dependency properties:
CLR "wrapper": The actual get and set implementations for the property. These
implementations incorporate the dependency property identifier by using it in the
GetValue and SetValue calls, thus providing the backing for the property using the
WPF property system.
The following example defines the IsSpinning dependency property, and shows the
relationship of the DependencyProperty identifier to the property that it backs.
C#
XAML
XAML supports a variety of syntax forms for setting properties. Which syntax to use for a
particular property will depend on the value type that a property uses, as well as other
factors such as the presence of a type converter. For more information on XAML syntax
for property setting, see XAML in WPF and XAML Syntax In Detail.
XAML
<Button Content="Button!">
<Button.Background>
<ImageBrush ImageSource="wavy.jpg"/>
</Button.Background>
</Button>
C#
Getting a property value is also essentially a call to the get "wrapper" implementation:
C#
double whatWidth;
whatWidth = myButton.Width;
You can also call the property system APIs GetValue and SetValue directly. This is not
typically necessary if you are using existing properties (the wrappers are more
convenient, and provide better exposure of the property for developer tools), but calling
the APIs directly is appropriate for certain scenarios.
Properties can be also set in XAML and then accessed later in code, through code-
behind. For details, see Code-Behind and XAML in WPF.
Resources
Data binding
Styles
Animations
Metadata overrides
XAML
<DockPanel.Resources>
<SolidColorBrush x:Key="MyBrush" Color="Gold"/>
</DockPanel.Resources>
Once the resource is defined, you can reference the resource and use it to provide a
property value:
XAML
7 Note
Resources are treated as a local value, which means that if you set another local
value, you will eliminate the resource reference. For more information, see
Dependency Property Value Precedence.
Data binding
A dependency property can reference a value through data binding. Data binding works
through a specific markup extension syntax in XAML, or the Binding object in code. With
data binding, the final property value determination is deferred until run time, at which
time the value is obtained from a data source.
The following example sets the Content property for a Button, using a binding declared
in XAML. The binding uses an inherited data context and an XmlDataProvider data
source (not shown). The binding itself specifies the desired source property by XPath
within the data source.
XAML
7 Note
Bindings are treated as a local value, which means that if you set another local
value, you will eliminate the binding. For details, see Dependency Property Value
Precedence.
Styles
Styles and templates are two of the chief motivating scenarios for using dependency
properties. Styles are particularly useful for setting properties that define application
user interface (UI). Styles are typically defined as resources in XAML. Styles interact with
the property system because they typically contain "setters" for particular properties, as
well as "triggers" that change a property value based on the real-time value for another
property.
The following example creates a simple style (which would be defined inside a
Resources dictionary, not shown), then applies that style directly to the Style property
for a Button. The setter within the style sets the Background property for a styled Button
to green.
XAML
<Style x:Key="GreenButtonStyle">
<Setter Property="Control.Background" Value="Green"/>
</Style>
XAML
Animations
Dependency properties can be animated. When an animation is applied and is running,
the animated value operates at a higher precedence than any value (such as a local
value) that the property otherwise has.
The following example animates the Background on a Button property (technically, the
Background is animated by using property element syntax to specify a blank
SolidColorBrush as the Background, then the Color property of that SolidColorBrush is
the property that is directly animated).
XAML
<Button>I am animated
<Button.Background>
<SolidColorBrush x:Name="AnimBrush"/>
</Button.Background>
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Loaded">
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetName="AnimBrush"
Storyboard.TargetProperty="(SolidColorBrush.Color)"
From="Red" To="Green" Duration="0:0:5"
AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
For more information on animating properties, see Animation Overview and Storyboards
Overview.
Metadata overrides
You can change certain behaviors of a dependency property by overriding the metadata
for that property when you derive from the class that originally registers the
dependency property. Overriding metadata relies on the DependencyProperty identifier.
Overriding metadata does not require reimplementing the property. The metadata
change is handled natively by the property system; each class potentially holds
individual metadata for all properties that are inherited from base classes, on a per-type
basis.
C#
7 Note
Property value inheritance behavior is not globally enabled for all dependency
properties, because the calculation time for inheritance does have some
performance impact. Property value inheritance is typically only enabled for
properties where a particular scenario suggests that property value inheritance is
appropriate. You can determine whether a dependency property inherits by looking
at the Dependency Property Information section for that dependency property in
the SDK reference.
The following example shows a binding, and sets the DataContext property that
specifies the source of the binding, which was not shown in the earlier binding example.
Any subsequent bindings in child objects do not need to specify the source, they can
use the inherited value from DataContext in the parent StackPanel object. (Alternatively,
a child object could instead choose to directly specify its own DataContext or a Source
in the Binding, and to deliberately not use the inherited value for data context of its
bindings.)
XAML
Consider the following example. The example includes a style that applies to all buttons
and their Background properties, but then also specifies one button with a locally set
Background value.
7 Note
The SDK documentation uses the terms "local value" or "locally set value"
occasionally when discussing dependency properties. A locally set value is a
property value that is set directly on an object instance in code, or as an attribute
on an element in XAML.
In principle, for the first button, the property is set twice, but only one value applies: the
value with the highest precedence. A locally set value has the highest precedence
(except for a running animation, but no animation applies in this example) and thus the
locally set value is used instead of the style setter value for the background on the first
button. The second button has no local value (and no other value with higher
precedence than a style setter) and thus the background in that button comes from the
style setter.
XAML
<StackPanel>
<StackPanel.Resources>
<Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Red"/>
</Style>
</StackPanel.Resources>
<Button Background="Green">I am NOT red!</Button>
<Button>I am styled red</Button>
</StackPanel>
7 Note
There are a number of properties defined on WPF elements that are not
dependency properties. By and large, properties were implemented as dependency
properties only when there were needs to support at least one of the scenarios
enabled by the property system: data binding, styling, animation, default value
support, inheritance, attached properties, or invalidation.
See also
Custom Dependency Properties
Read-Only Dependency Properties
XAML in WPF
WPF Architecture
Attached Properties Overview
Article • 03/17/2022
Prerequisites
This article assumes that you understand dependency properties from the perspective of
a consumer of existing dependency properties on Windows Presentation Foundation
(WPF) classes, and have read the Dependency Properties Overview. To follow the
examples in this article, you should also understand XAML and know how to write WPF
applications.
XAML
<DockPanel>
<TextBox DockPanel.Dock="Top">Enter text</TextBox>
</DockPanel>
The usage is somewhat similar to a static property; you always reference the type
DockPanel that owns and registers the attached property, rather than referring to any
instance specified by name.
Also, because an attached property in XAML is an attribute that you set in markup, only
the set operation has any relevance. You cannot directly get a property in XAML,
although there are some indirect mechanisms for comparing values, such as triggers in
styles (for details, see Styling and Templating).
The type that defines the attached property is designed so that it can be the
parent element of the elements that will set values for the attached property. The
type then iterates its child objects through internal logic against some object tree
structure, obtains the values, and acts on those values in some manner.
The type that defines the attached property will be used as the child element for a
variety of possible parent elements and content models.
The type that defines the attached property represents a service. Other types set
values for the attached property. Then, when the element that set the property is
evaluated in the context of the service, the attached property values are obtained
through internal logic of the service class.
An Example of a Parent-Defined Attached Property
The most typical scenario where WPF defines an attached property is when a parent
element supports a child element collection, and also implements a behavior where the
specifics of the behavior are reported individually for each child element.
DockPanel defines the DockPanel.Dock attached property, and DockPanel has class-level
code as part of its rendering logic (specifically, MeasureOverride and ArrangeOverride).
A DockPanel instance will always check to see whether any of its immediate child
elements have set a value for DockPanel.Dock. If so, those values become input for the
rendering logic applied to that particular child element. Nested DockPanel instances
each treat their own immediate child element collections, but that behavior is
implementation-specific to how DockPanel processes DockPanel.Dock values. It is
theoretically possible to have attached properties that influence elements beyond the
immediate parent. If the DockPanel.Dock attached property is set on an element that
has no DockPanel parent element to act upon it, no error or exception is raised. This
simply means that a global property value was set, but it has no current DockPanel
parent that could consume the information.
The following example shows how you can set an attached property in code. In this
example, myCheckBox is an instance of the CheckBox class.
C#
If you want to enable property value inheritance on a property, you should use attached
properties rather than non-attached dependency properties. For details, see Property
Value Inheritance.
Another scenario for using an attached property is when your class represents a service,
and you want classes to be able to integrate the service more transparently.
Yet another scenario is to receive Visual Studio WPF Designer support, such as
Properties window editing. For more information, see Control Authoring Overview.
As mentioned before, you should register as an attached property if you want to use
property value inheritance.
value of the RegisterAttached method. The field name must match the attached
property name, appended with the string Property , to follow the established WPF
pattern of naming the identifying fields versus the properties that they represent. The
attached property provider must also provide static GetPropertyName and
SetPropertyName methods as accessors for the attached property; failing to do this
results in the property system being unable to use your attached property.
7 Note
If you omit the attached property's get accessor, data binding on the property will
not work in design tools, such as Visual Studio and Blend for Visual Studio.
The target object can be specified as a more specific type in your implementation.
For example, the DockPanel.GetDock method types the parameter as UIElement,
because the attached property is only intended to be set on UIElement instances.
The return value can be specified as a more specific type in your implementation.
For example, the GetDock method types it as Dock, because the value can only be
set to that enumeration.
The Set Accessor
The signature for the SetPropertyName accessor must be:
The target object can be specified as a more specific type in your implementation.
For example, the SetDock method types it as UIElement, because the attached
property is only intended to be set on UIElement instances.
The value object can be specified as a more specific type in your implementation.
For example, the SetDock method types it as Dock, because the value can only be
set to that enumeration. Remember that the value for this method is the input
coming from the XAML loader when it encounters your attached property in an
attached property usage in markup. That input is the value specified as a XAML
attribute value in markup. Therefore there must be type conversion, value
serializer, or markup extension support for the type you use, such that the
appropriate type can be created from the attribute value (which is ultimately just a
string).
The following example shows the dependency property registration (using the
RegisterAttached method), as well as the GetPropertyName and SetPropertyName
accessors. In the example, the attached property name is IsBubbleSource . Therefore, the
accessors must be named GetIsBubbleSource and SetIsBubbleSource .
C#
AttachedPropertyBrowsableAttribute
AttachedPropertyBrowsableForChildrenAttribute
AttachedPropertyBrowsableForTypeAttribute
AttachedPropertyBrowsableWhenAttributePresentAttribute
For more advanced usage scenarios for dependency properties and attached
properties, see Custom Dependency Properties.
See also
DependencyProperty
Dependency Properties Overview
Custom Dependency Properties
XAML in WPF
Register an Attached Property
Custom Dependency Properties
Article • 03/17/2022
This topic describes the reasons that Windows Presentation Foundation (WPF)
application developers and component authors might want to create custom
dependency property, and describes the implementation steps as well as some
implementation options that can improve performance, usability, or versatility of the
property.
Prerequisites
This topic assumes that you understand dependency properties from the perspective of
a consumer of existing dependency properties on WPF classes, and have read the
Dependency Properties Overview topic. In order to follow the examples in this topic, you
should also understand WPF applications.
You want your property to be settable in a style. For more information, see Styling
and Templating.
You want your property to support data binding. For more information about data
binding dependency properties, see Bind the Properties of Two Controls.
You want your property to be settable with a dynamic resource reference. For more
information, see XAML Resources.
You want to inherit a property value automatically from a parent element in the
element tree. In this case, register with the RegisterAttached method, even if you
also create a property wrapper for CLR access. For more information, see Property
Value Inheritance.
You want your property to be animatable. For more information, see Animation
Overview.
You want the property system to report when the previous value of the property
has been changed by actions taken by the property system, the environment, or
the user, or by reading and using styles. By using property metadata, your property
can specify a callback method that will be invoked each time the property system
determines that your property value was definitively changed. A related concept is
property value coercion. For more information, see Dependency Property Callbacks
and Validation.
You want to use established metadata conventions that are also used by WPF
processes, such as reporting whether changing a property value should require the
layout system to recompose the visuals for an element. Or you want to be able to
use metadata overrides so that derived classes can change metadata-based
characteristics such as the default value.
You want properties of a custom control to receive Visual Studio WPF Designer
support, such as Properties window editing. For more information, see Control
Authoring Overview.
When you examine these scenarios, you should also consider whether you can achieve
your scenario by overriding the metadata of an existing dependency property, rather
than implementing a completely new property. Whether a metadata override is practical
depends on your scenario and how closely that scenario resembles the implementation
in existing WPF dependency properties and classes. For more information about
overriding metadata on existing properties, see Dependency Property Metadata.
Register the property name with the property system, specifying an owner type
and the type of the property value. Also specify the property metadata, if used.
C#
The dependency property itself will have a basic name, "AquariumGraphic" as in this
example, which is given as the first parameter of Register. That name must be unique
within each registering type. Dependency properties inherited through base types are
considered to be already part of the registering type; names of inherited properties
cannot be registered again. However, there is a technique for adding a class as owner of
a dependency property even when that dependency property is not inherited; for
details, see Dependency Property Metadata.
When you create the identifier field, name this field by the name of the property as you
registered it, plus the suffix Property . This field is your identifier for the dependency
property, and it will be used later as an input for the SetValue and GetValue calls you will
make in the wrappers, by any other code access to the property by your own code, by
any external code access you allow, by the property system, and potentially by XAML
processors.
7 Note
Defining the dependency property in the class body is the typical implementation,
but it is also possible to define a dependency property in the class static
constructor. This approach might make sense if you need more than one line of
code to initialize the dependency property.
In all but exceptional circumstances, your wrapper implementations should perform only
the GetValue and SetValue actions, respectively. The reason for this is discussed in the
topic XAML Loading and Dependency Properties.
All existing public dependency properties that are provided on the WPF classes use this
simple wrapper implementation model; most of the complexity of how dependency
properties work is either inherently a behavior of the property system, or is
implemented through other concepts such as coercion or property change callbacks
through property metadata.
C#
Again, by convention, the name of the wrapper property must be the same as the name
chosen and given as first parameter of the Register call that registered the property. If
your property does not follow the convention, this does not necessarily disable all
possible uses, but you will encounter several notable issues:
Most tools and designers must rely on the naming conventions to properly
serialize XAML, or to provide designer environment assistance at a per-property
level.
The current implementation of the WPF XAML loader bypasses the wrappers
entirely, and relies on the naming convention when processing attribute values. For
more information, see XAML Loading and Dependency Properties.
For FrameworkPropertyMetadata, you can also specify metadata option flags for your
property. These flags are converted into discrete properties on the property metadata
after registration and are used to communicate certain conditionals to other processes
such as the layout engine.
If your property (or changes in its value) affects the user interface (UI), and in
particular affects how the layout system should size or render your element in a
page, set one or more of the following flags: AffectsMeasure, AffectsArrange,
AffectsRender.
AffectsRender indicates that some other change has occurred that will not affect
layout and measure, but does require another render. An example would be a
property that changes a color of an existing element, such as "Background".
These flags are often used as a protocol in metadata for your own override
implementations of property system or layout callbacks. For instance, you might
have an OnPropertyChanged callback that will call InvalidateArrange if any
property of the instance reports a value change and has AffectsArrange as true
in its metadata.
Some properties may affect the rendering characteristics of the containing parent
element, in ways above and beyond the changes in required size mentioned
above. An example is the MinOrphanLines property used in the flow document
model, where changes to that property can change the overall rendering of the
flow document that contains the paragraph. Use AffectsParentArrange or
AffectsParentMeasure to identify similar cases in your own properties.
By default, data binding Mode for dependency properties defaults to OneWay. You
can always change the binding to be TwoWay per binding instance; for details, see
Specify the Direction of the Binding. But as the dependency property author, you
can choose to make the property use TwoWay binding mode by default. An
example of an existing dependency property is MenuItem.IsSubmenuOpen; the
scenario for this property is that the IsSubmenuOpen setting logic and the
compositing of MenuItem interact with the default theme style. The
IsSubmenuOpen property logic uses data binding natively to maintain the state of
the property in accordance to other state properties and method calls. Another
example property that binds TwoWay by default is TextBox.Text.
Set the Journal flag to indicate if your dependency property should be detected or
used by navigation journaling services. An example is the SelectedIndex property;
any item selected in a selection control should be persisted when the journaling
history is navigated.
See also
Dependency Properties Overview
Dependency Property Metadata
Control Authoring Overview
Collection-Type Dependency Properties
Dependency Property Security
XAML Loading and Dependency Properties
Safe Constructor Patterns for DependencyObjects
Dependency Property Metadata
Article • 02/06/2023
Prerequisites
This topic assumes that you understand dependency properties from the perspective of
a consumer of existing dependency properties on WPF applications.
Default value for the dependency property, if no other value can be determined for
the dependency property by local value, style, inheritance, etc. For a thorough
discussion of how default values participate in the precedence used by the
property system when assigning values for dependency properties, see
Dependency Property Value Precedence.
Metadata APIs
The type that reports most of the metadata information used by the property system is
the PropertyMetadata class. Metadata instances are optionally specified when
dependency properties are registered with the property system, and can be specified
again for additional types that either add themselves as owners or override metadata
they inherit from the base class dependency property definition. (For cases where a
property registration does not specify metadata, a default PropertyMetadata is created
with default values for that class.)The registered metadata is returned as
PropertyMetadata when you call the various GetMetadata overloads that get metadata
from a dependency property on a DependencyObject instance.
The PropertyMetadata class is then derived from to provide more specific metadata for
architectural divisions such as the WPF framework-level classes. UIPropertyMetadata
adds animation reporting, and FrameworkPropertyMetadata provides the WPF
framework-level properties mentioned in the previous section. When dependency
properties are registered, they can be registered with these PropertyMetadata derived
classes. When the metadata is examined, the base PropertyMetadata type can
potentially be cast to the derived classes so that you can examine the more specific
properties.
7 Note
If the scenario you are trying to enable for a dependency property on a type cannot be
accomplished by modifying characteristics of existing dependency properties, it might
then be necessary to create a derived class, and then to declare a custom dependency
property on your derived class. A custom dependency property behaves identically to
dependency properties defined by the WPF APIs. For more details about custom
dependency properties, see Custom Dependency Properties.
One notable characteristic of a dependency property that you cannot override is its
value type. If you are inheriting a dependency property that has the approximate
behavior you require, but you require a different type for it, you will have to implement
a custom dependency property and perhaps link the properties through type conversion
or other implementation on your custom class. Also, you cannot replace an existing
ValidateValueCallback, because this callback exists in the registration field itself and not
within its metadata.
Overriding Metadata
The purpose of overriding metadata is primarily so that you have the opportunity to
change the various metadata-derived behaviors that are applied to the dependency
property as it exists on your type. The reasons for this are explained in more detail in the
Metadata section. For more information including some code examples, see Override
Metadata for a Dependency Property.
Property metadata can be supplied for a dependency property during the registration
call (Register). However, in many cases, you might want to provide type-specific
metadata for your class when it inherits that dependency property. You can do this by
calling the OverrideMetadata method. For an example from the WPF APIs, the
FrameworkElement class is the type that first registers the Focusable dependency
property. But the Control class overrides metadata for the dependency property to
provide its own initial default value, changing it from false to true , and otherwise re-
uses the original Focusable implementation.
When you override metadata, the different metadata characteristics are either merged
or replaced.
7 Note
As well as adding itself as owner through the property system utility methods, the
adding class should declare additional public members on itself in order to make the
dependency property] a full participant in the property system with exposure to both
code and markup. A class that adds an existing dependency property has the same
responsibilities as far as exposing the object model for that dependency property as
does a class that defines a new custom dependency property. The first such member to
expose is a dependency property identifier field. This field should be a public static
readonly field of type DependencyProperty, which is assigned to the return value of the
AddOwner call. The second member to define is the common language runtime (CLR)
"wrapper" property. The wrapper makes it much more convenient to manipulate your
dependency property in code (you avoid calls to SetValue each time, and can make that
call only once in the wrapper itself). The wrapper is implemented identically to how it
would be implemented if you were registering a custom dependency property. For more
information about implementing a dependency property, see Custom Dependency
Properties and Add an Owner Type for a Dependency Property.
You can call AddOwner for a dependency property that is defined as an attached
property by the owner class. Generally the reason for doing this is to expose the
previously attached property as a non-attached dependency property. You then will
expose the AddOwner return value as a public static readonly field for use as the
dependency property identifier, and will define appropriate "wrapper" properties so that
the property appears in the members table and supports a non-attached property usage
in your class.
See also
PropertyMetadata
DependencyObject
DependencyProperty
GetMetadata
Dependency Properties Overview
Framework Property Metadata
Dependency Property Callbacks and
Validation
Article • 02/06/2023
This topic describes how to create dependency properties using alternative custom
implementations for property-related features such as validation determination,
callbacks that are invoked whenever the property's effective value is changed, and
overriding possible outside influences on value determination. This topic also discusses
scenarios where expanding on the default property system behaviors by using these
techniques is appropriate.
Prerequisites
This topic assumes that you understand the basic scenarios of implementing a
dependency property, and how metadata is applied to a custom dependency property.
See Custom Dependency Properties and Dependency Property Metadata for context.
Validation Callbacks
Validation callbacks can be assigned to a dependency property when you first register it.
The validation callback is not part of property metadata; it is a direct input of the
Register method. Therefore, once a validation callback is created for a dependency
property, it cannot be overridden by a new implementation.
C#
The callbacks are implemented such that they are provided an object value. They return
true if the provided value is valid for the property; otherwise, they return false . It is
assumed that the property is of the correct type per the type registered with the
property system, so checking type within the callbacks is not ordinarily done. The
callbacks are used by the property system in a variety of different operations. This
includes the initial type initialization by default value, programmatic change by invoking
SetValue, or attempts to override metadata with new default value provided. If the
validation callback is invoked by any of these operations, and returns false , then an
exception will be raised. Application writers must be prepared to handle these
exceptions. A common use of validation callbacks is validating enumeration values, or
constraining values of integers or doubles when the property sets measurements that
must be zero or greater.
The following is example code for a very simple validation callback scenario: validating
that a property that is typed as the Double primitive is not PositiveInfinity or
NegativeInfinity.
C#
A typical scenario for using a linkage of dependency properties is when you have a user
interface driven property where the element holds one property each for the minimum
and maximum value, and a third property for the actual or current value. Here, if the
maximum was adjusted in such a way that the current value exceeded the new
maximum, you would want to coerce the current value to be no greater than the new
maximum, and a similar relationship for minimum to current.
The following is very brief example code for just one of the three dependency properties
that illustrate this relationship. The example shows how the CurrentReading property of
a Min/Max/Current set of related *Reading properties is registered. It uses the validation
as shown in the previous section.
C#
The property changed callback for Current is used to forward the change to other
dependent properties, by explicitly invoking the coerce value callbacks that are
registered for those other properties:
C#
C#
7 Note
Default values of properties are not coerced. A property value equal to the default
value might occur if a property value still has its initial default, or through clearing
other values with ClearValue.
The coerce value and property changed callbacks are part of property metadata.
Therefore, you can change the callbacks for a particular dependency property as it exists
on a type that you derive from the type that owns the dependency property, by
overriding the metadata for that property on your type.
There is nothing technically wrong with complex dependencies, but they can be a slight
performance detriment if they require large numbers of reevaluations, and can also be
confusing to users if they affect the UI directly. Be careful with property changed and
coerce value callbacks and make sure that the coercion being attempted can be treated
as unambiguously as possible, and does not "overconstrain".
See also
Dependency Properties Overview
Dependency Property Metadata
Custom Dependency Properties
Framework Property Metadata
Article • 02/06/2023
Framework property metadata options are reported for the properties of object
elements considered to be at the WPF framework level in the WPF presentation APIs
and executables. Framework property metadata is queried by these systems to
determine feature-specific characteristics of particular element properties.
Prerequisites
This topic assumes that you understand dependency properties from the perspective of
a consumer of existing dependency properties on Windows Presentation Foundation
(WPF) classes, and have read the Dependency Properties Overview. You should also have
read Dependency Property Metadata.
7 Note
The term "inherits" in the context of property values means something
specific for dependency properties; it means that child elements can inherit
the actual dependency property value from parent elements because of a
WPF framework-level capability of the WPF property system. It has nothing to
do directly with managed code type and members inheritance through
derived types. For details, see Property Value Inheritance.
Reading FrameworkPropertyMetadata
Each of the properties linked above are the specific properties that the
FrameworkPropertyMetadata adds to its immediate base class UIPropertyMetadata.
Each of these properties will be false by default. A metadata request for a property
where knowing the value of these properties is important should attempt to cast the
returned metadata to FrameworkPropertyMetadata, and then check the values of the
individual properties as needed.
Specifying Metadata
When you create a new metadata instance for purposes of applying metadata to a new
dependency property registration, you have the choice of which metadata class to use:
the base PropertyMetadata or some derived class such as FrameworkPropertyMetadata.
In general, you should use FrameworkPropertyMetadata, particularly if your property
has any interaction with property system and WPF functions such as layout and data
binding. Another option for more sophisticated scenarios is to derive from
FrameworkPropertyMetadata to create your own metadata reporting class with extra
information carried in its members. Or you might use PropertyMetadata or
UIPropertyMetadata to communicate the degree of support for features of your
implementation.
2. Use one of the signatures without a flags parameter, and then set each reporting
Boolean property on FrameworkPropertyMetadata to true for each desired
characteristic change. If you do this, you must set these properties before any
elements with this dependency property are constructed; the Boolean properties
are read-write in order to allow this behavior of avoiding the flags parameter and
still populate the metadata, but the metadata must become effectively sealed
before property use. Thus, attempting to set the properties after metadata is
requested will be an invalid operation.
See also
GetMetadata
Dependency Property Metadata
Dependency Properties Overview
Custom Dependency Properties
Dependency Property Value Precedence
Article • 02/06/2023
This topic explains how the workings of the Windows Presentation Foundation (WPF)
property system can affect the value of a dependency property, and describes the
precedence by which aspects of the property system apply to the effective value of a
property.
Prerequisites
This topic assumes that you understand dependency properties from the perspective of
a consumer of existing dependency properties on WPF classes, and have read
Dependency Properties Overview. To follow the examples in this topic, you should also
understand WPF applications.
XAML
<StackPanel>
<StackPanel.Resources>
<ControlTemplate x:Key="ButtonTemplate" TargetType="{x:Type
Button}">
<Border Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</StackPanel.Resources>
With the exception of animated values and coercion, local property sets are set at the
highest precedence. If you set a value locally you can expect that the value will be
honored, even above any styles or control templates. Here in the example, Background
is set to Red locally. Therefore, the style defined in this scope, even though it is an
implicit style that would otherwise apply to all elements of that type in that scope, is not
the highest precedence for giving the Background property its value. If you removed the
local value of Red from that Button instance, then the style would have precedence and
the button would obtain the Background value from the style. Within the style, triggers
take precedence, so the button will be blue if the mouse is over it, and green otherwise.
1. Property system coercion. For details on coercion, see Coercion, Animation, and
Base Value later in this topic.
3. Local value. A local value might be set through the convenience of the "wrapper"
property, which also equates to setting as an attribute or property element in
XAML, or by a call to the SetValue API using a property of a specific instance. If you
set a local value by using a binding or a resource, these each act in the precedence
as if a direct value was set.
5. Implicit style. Applies only to the Style property. The Style property is filled by
any style resource with a key that matches the type of that element. That style
resource must exist either in the page or the application; lookup for an implicit
style resource does not proceed into the themes.
6. Style triggers. The triggers within styles from page or application (these styles
might be either explicit or implicit styles, but not from the default styles, which
have lower precedence).
7. Template triggers. Any trigger from a template within a style, or a directly applied
template.
8. Style setters. Values from a Setter within styles from page or application.
9. Default (theme) style. For details on when this applies, and how theme styles
relate to the templates within theme styles, see Default (Theme) Styles later in this
topic. Within a default style, the following order of precedence applies:
10. Inheritance. A few dependency properties inherit their values from parent element
to child elements, such that they need not be set specifically on each element
throughout an application. For details see Property Value Inheritance.
11. Default value from dependency property metadata. Any given dependency
property may have a default value as established by the property system
registration of that particular property. Also, derived classes that inherit a
dependency property have the option to override that metadata (including the
default value) on a per-type basis. See Dependency Property Metadata for more
information. Because inheritance is checked before default value, for an inherited
property, a parent element default value takes precedence over a child element.
Consequently, if an inheritable property is not set anywhere, the default value as
specified on the root or parent is used instead of the child element default value.
TemplatedParent
TemplatedParent as a precedence item does not apply to any property of an element
that you declare directly in standard application markup. The TemplatedParent concept
exists only for child items within a visual tree that come into existence through the
application of the template. When the property system searches the TemplatedParent
template for a value, it is searching the template that created that element. The property
values from the TemplatedParent template generally act as if they were set as a local
value on the child element, but this lesser precedence versus the local value exists
because the templates are potentially shared. For details, see TemplatedParent.
Explicit style. The Style property is set directly. In most scenarios, the style is not
defined inline, but instead is referenced as a resource, by explicit key. In this case
the Style property itself acts as if it were a local value, precedence item 3.
Implicit style. The Style property is not set directly. However, the Style exists at
some level in the resource lookup sequence (page, application) and is keyed using
a resource key that matches the type the style is to be applied to. In this case, the
Style property itself acts by a precedence identified in the sequence as item 5. This
condition can be detected by using DependencyPropertyHelper against the Style
property and looking for ImplicitStyleReference in the results.
Default style, also known as theme style. The Style property is not set directly, and
in fact will read as null up until run time. In this case, the style comes from the
run-time theme evaluation that is part of the WPF presentation engine.
For implicit styles not in themes, the type must match exactly - a MyButton Button -
derived class will not implicitly use a style for Button .
The most important information that is found within a default style for a control is its
control template, which exists in the theme style as a setter for its Template property. If
there were no template from default styles, a control without a custom template as part
of a custom style would have no visual appearance at all. The template from the default
style gives the visual appearance of each control a basic structure, and also defines the
connections between properties defined in the visual tree of the template and the
corresponding control class. Each control exposes a set of properties that can influence
the visual appearance of the control without completely replacing the template. For
example, consider the default visual appearance of a Thumb control, which is a
component of a ScrollBar.
A Thumb has certain customizable properties. The default template of a Thumb creates
a basic structure / visual tree with several nested Border components to create a bevel
look. If a property that is part of the template is intended to be exposed for
customization by the Thumb class, then that property must be exposed by a
TemplateBinding, within the template. In the case of Thumb, various properties of these
borders share a template binding to properties such as Background or BorderThickness.
But certain other properties or visual arrangements are hard-coded into the control
template or are bound to values that come directly from the theme, and cannot be
changed short of replacing the entire template. Generally, if a property comes from a
templated parent and is not exposed by a template binding, it cannot be adjusted by
styles because there is no easy way to target it. But that property could still be
influenced by property value inheritance in the applied template, or by default value.
The theme styles use a type as the key in their definitions. However, when themes are
applied to a given element instance, themes lookup for this type is performed by
checking the DefaultStyleKey property on a control. This is in contrast to using the literal
Type, as implicit styles do. The value of DefaultStyleKey would inherit to derived classes
even if the implementer did not change it (the intended way of changing the property is
not to override it at the property level, but to instead change its default value in
property metadata). This indirection enables base classes to define the theme styles for
derived elements that do not otherwise have a style (or more importantly, do not have a
template within that style and would thus have no default visual appearance at all).
Thus, you can derive MyButton from Button and will still get the Button default template.
If you were the control author of MyButton and you wanted a different behavior, you
could override the dependency property metadata for DefaultStyleKey on MyButton to
return a different key, and then define the relevant theme styles including template for
MyButton that you must package with your MyButton control. For more details on
themes, styles, and control authoring, see Control Authoring Overview.
Dynamic resource references are not strictly speaking part of the property system, but
they do have a lookup order of their own which interacts with the sequence listed
above. That precedence is documented more thoroughly in the XAML Resources. The
basic summation of that precedence is: element to page root, application, theme,
system.
Dynamic resources and bindings have the precedence of where they were set, but the
value is deferred. One consequence of this is that if you set a dynamic resource or
binding to a local value, any change to the local value replaces the dynamic resource or
binding entirely. Even if you call the ClearValue method to clear the locally set value, the
dynamic resource or binding will not be restored. In fact, if you call ClearValue on a
property that has a dynamic resource or binding in place (with no literal local value),
they are cleared by the ClearValue call too.
SetCurrentValue
The SetCurrentValue method is another way to set a property, but it is not in the order
of precedence. Instead, SetCurrentValue enables you to change the value of a property
without overwriting the source of a previous value. You can use SetCurrentValue any
time that you want to set a value without giving that value the precedence of a local
value. For example, if a property is set by a trigger and then assigned another value via
SetCurrentValue, the property system still respects the trigger and the property will
change if the trigger’s action occurs. SetCurrentValue enables you to change the
property’s value without giving it a source with a higher precedence. Likewise, you can
use SetCurrentValue to change the value of a property without overwriting a binding.
For an animation, the base value can have an effect on the animated value, if that
animation does not specify both "From" and "To" for certain behaviors, or if the
animation deliberately reverts to the base value when completed. To see this in practice,
run the From, To, and By Animation Target Values Sample . Try setting the local values
of the rectangle height in the example, such that the initial local value differs from any
"From" in the animation. You will note that the animations start right away using the
"From" values and replace the base value once started. The animation might specify to
return to the value found before animation once it is completed by specifying the Stop
FillBehavior. Afterwards, normal precedence is used for the base value determination.
Coercion applies at the highest level of all. Even an already running animation is subject
to value coercion. Certain existing dependency properties in WPF have built-in coercion.
For a custom dependency property, you define the coercion behavior for a custom
dependency property by writing a CoerceValueCallback and passing the callback as part
of metadata when you create the property. You can also override coercion behavior of
existing properties by overriding the metadata on that property in a derived class.
Coercion interacts with the base value in such a way that the constraints on coercion are
applied as those constraints exist at the time, but the base value is still retained.
Therefore, if constraints in coercion are later lifted, the coercion will return the closest
value possible to that base value, and potentially the coercion influence on a property
will cease as soon as all constraints are lifted. For more information about coercion
behavior, see Dependency Property Callbacks and Validation.
Trigger Behaviors
Controls often define trigger behaviors as part of their default style in themes. Setting
local properties on controls might prevent the triggers from being able to respond to
user-driven events either visually or behaviorally. The most common use of a property
trigger is for control or state properties such as IsSelected. For example, by default when
a Button is disabled (trigger for IsEnabled is false ) then the Foreground value in the
theme style is what causes the control to appear "grayed out". But if you have set a local
Foreground value, that normal gray-out color will be overruled in precedence by your
local property set, even in this property-triggered scenario. Be cautious of setting values
for properties that have theme-level trigger behaviors and make sure you are not
unduly interfering with the intended user experience for that control.
See also
DependencyObject
DependencyProperty
Dependency Properties Overview
Custom Dependency Properties
Dependency Property Callbacks and Validation
Read-Only Dependency Properties
Article • 02/06/2023
Prerequisites
This topic assumes that you understand the basic scenarios of implementing a
dependency property, and how metadata is applied to a custom dependency property.
See Custom Dependency Properties and Dependency Property Metadata for context.
By virtue of not being settable, read-only dependency properties aren't appropriate for
many of the scenarios for which dependency properties normally offer a solution
(namely: data binding, directly stylable to a value, validation, animation, inheritance).
Despite not being settable, read-only dependency properties still have some of the
additional capabilities supported by dependency properties in the property system. The
most important remaining capability is that the read-only dependency property can still
be used as a property trigger in a style. You can't enable triggers with a normal common
language runtime (CLR) property; it needs to be a dependency property. The
aforementioned IsMouseOver property is a perfect example of a scenario where it might
be quite useful to define a style for a control, where some visible property such as a
background, foreground, or similar properties of composited elements within the
control will change when the user places a mouse over some defined region of your
control. Changes in a read-only dependency property can also be detected and
reported by the property system's inherent invalidation processes, and this in fact
supports the property trigger functionality internally.
Creating Custom Read-Only Dependency
Properties
Make sure to read the section above regarding why read-only dependency properties
won't work for many typical dependency-property scenarios. But if you have an
appropriate scenario, you may wish to create your own read-only dependency property.
When registering your property, call the RegisterReadOnly method instead of the
normal Register method for property registration.
When implementing the CLR "wrapper" property, make sure that the wrapper too
doesn't have a set implementation, so that there is no inconsistency in read-only
state for the public wrapper you expose.
Whatever private field or value you have backing your read-only dependency property
can of course be fully writable using whatever logic you decide. However, the most
straightforward way to set the property either initially or as part of runtime logic is to
use the property system's APIs, rather than circumventing the property system and
setting the private backing field directly. In particular, there is a signature of SetValue
that accepts a parameter of type DependencyPropertyKey. How and where you set this
value programmatically within your application logic will affect how you may wish to set
access on the DependencyPropertyKey created when you first registered the
dependency property. If you handle this logic all within the class you could make it
private, or if you require it to be set from other portions of the assembly you might set it
internal. One approach is to call SetValue within a class event handler of a relevant event
that informs a class instance that the stored property value needs to be changed.
Another approach is to tie dependency properties together by using paired
PropertyChangedCallback and CoerceValueCallback callbacks as part of those
properties' metadata during registration.
See also
Dependency Properties Overview
Custom Dependency Properties
Styling and Templating
Property Value Inheritance
Article • 02/06/2023
Attached properties are conceptually similar to global properties; you can check for the
value on any DependencyObject and get a valid result. The typical scenario for attached
properties is to set property values on child elements, and that scenario is more
effective if the property in question is an attached property that is always implicitly
present as an attached property on each element (DependencyObject) in the tree.
7 Note
See also
Dependency Property Metadata
Attached Properties Overview
Dependency Property Value Precedence
Dependency Property Security
Article • 02/06/2023
If you are writing your own dependency properties, you should declare the wrappers
and the DependencyProperty identifier field as public members, so that callers do not
get misleading information about the true access level of that property (because of its
store being implemented as a dependency property).
For a custom dependency property, you can register your property as a read-only
dependency property, and this does provide an effective means of preventing a
property being set by anyone that does not hold a reference to the
DependencyPropertyKey for that property. For more information, see Read-Only
Dependency Properties.
7 Note
See also
Custom Dependency Properties
Safe Constructor Patterns for
DependencyObjects
Article • 02/06/2023
Generally, class constructors should not call callbacks such as virtual methods or
delegates, because constructors can be called as base initialization of constructors for a
derived class. Entering the virtual might be done at an incomplete initialization state of
any given object. However, the property system itself calls and exposes callbacks
internally, as part of the dependency property system. As simple an operation as setting
a dependency property value with SetValue call potentially includes a callback
somewhere in the determination. For this reason, you should be careful when setting
dependency property values within the body of a constructor, which can become
problematic if your type is used as a base class. There is a particular pattern for
implementing DependencyObject constructors that avoids specific problems with
dependency property states and the inherent callbacks, which is documented here.
DoNotCallOverridableMethodsInConstructors
This is a rule that is part of the default public rule set for FXCop. What this rule might be
reporting is a trace through the dependency property system that eventually calls a
dependency property system virtual method. This rule violation might continue to
appear even after following the recommended constructor patterns documented in this
topic, so you might need to disable or suppress that rule in your FXCop rule set
configuration.
The following example code (and subsequent examples) is a pseudo-C# example that
violates this rule and explains the problem:
C#
When application code calls new MyClass(objectvalue) , this calls the parameterless
constructor and base class constructors. Then it sets Property1 = object1 , which calls
the virtual method OnPropertyChanged on the owning MyClass DependencyObject. The
override refers to _myList , which has not been initialized yet.
One way to avoid these issues is to make sure that callbacks use only other dependency
properties, and that each such dependency property has an established default value as
part of its registered metadata.
C#
C#
C#
For cases where the base type has multiple signatures, you must deliberately match all
possible signatures with a constructor implementation of your own that uses the
recommended pattern of calling the class parameterless constructor before setting
further properties.
See also
Custom Dependency Properties
Dependency Properties Overview
Dependency Property Security
Collection-Type Dependency Properties
Article • 02/06/2023
This topic provides guidance and suggested patterns for how to implement a
dependency property where the type of the property is a collection type.
Consider the following example. The following section of the example shows the
definition for a class Aquarium , which contains a flaw with the default value. The class
defines the collection type dependency property AquariumObjects , which uses the
generic List<T> type with a FrameworkElement type constraint. In the Register(String,
Type, Type, PropertyMetadata) call for the dependency property, the metadata
establishes the default value to be a new generic List<T>.
2 Warning
The following code does not behave correctly.
C#
// ...
}
However, if you just left the code as shown, that single list default value is shared for all
instances of Aquarium . If you ran the following test code, which is intended to show how
you would instantiate two separate Aquarium instances and add a single different Fish
to each of them, you would see a surprising result:
C#
Instead of each collection having a count of one, each collection has a count of two! This
is because each Aquarium added its Fish to the default value collection, which resulted
from a single constructor call in the metadata and is therefore shared between all
instances. This situation is almost never what you want.
To correct this problem, you must reset the collection dependency property value to a
unique instance, as part of the class constructor call. Because the property is a read-only
dependency property, you use the SetValue(DependencyPropertyKey, Object) method to
set it, using the DependencyPropertyKey that is only accessible within the class.
C#
Now, if you ran that same test code again, you could see more expected results, where
each Aquarium supported its own unique collection.
There would be a slight variation on this pattern if you chose to have your collection
property be read-write. In that case, you could call the public set accessor from the
constructor to do the initialization, which would still be calling the nonkey signature of
SetValue(DependencyProperty, Object) within your set wrapper, using a public
DependencyProperty identifier.
See also
FreezableCollection<T>
XAML and Custom Classes for WPF
Data Binding Overview
Dependency Properties Overview
Custom Dependency Properties
Dependency Property Metadata
XAML Loading and Dependency
Properties
Article • 02/06/2023
The current WPF implementation of its WPF XAML processor uses property system
methods for dependency properties when loading binary XAML and processing
attributes that are dependency properties. This effectively bypasses the property
wrappers. When you implement custom dependency properties, you must account for
this behavior and should avoid placing any other code in your property wrapper other
than the property system methods GetValue and SetValue.
Prerequisites
This topic assumes that you understand dependency properties both as consumer and
author and have read Dependency Properties Overview and Custom Dependency
Properties. You should also have read XAML in WPF and XAML Syntax In Detail.
The type is looked up through a combination of xmlns and assembly attributes, but
identifying the members, determining which could support being set as an attribute,
and resolving what types the property values support would otherwise require extensive
reflection using PropertyInfo. Because dependency properties on a given type are
accessible as a storage table through the property system, the WPF implementation of
its XAML processor uses this table and infers that any given property ABC can be more
efficiently set by calling SetValue on the containing DependencyObject derived type,
using the dependency property identifier ABCProperty.
Implications for Custom Dependency
Properties
Because the current WPF implementation of the XAML processor behavior for property
setting bypasses the wrappers entirely, you should not put any additional logic into the
set definitions of the wrapper for your custom dependency property. If you put such
logic in the set definition, then the logic will not be executed when the property is set in
XAML rather than in code.
Similarly, other aspects of the XAML processor that obtain property values from XAML
processing also use GetValue rather than using the wrapper. Therefore, you should also
avoid any additional implementation in the get definition beyond the GetValue call.
C#
See also
Dependency Properties Overview
XAML in WPF
Dependency Property Metadata
Collection-Type Dependency Properties
Dependency Property Security
Safe Constructor Patterns for DependencyObjects
Properties How-to Topics
Article • 02/06/2023
In This Section
Implement a Dependency Property
Add an Owner Type for a Dependency Property
Register an Attached Property
Override Metadata for a Dependency Property
Reference
DependencyProperty
PropertyMetadata
FrameworkPropertyMetadata
DependencyObject
Related Sections
Properties
How to: Implement a Dependency
Property
Article • 02/06/2023
This example shows how to back a common language runtime (CLR) property with a
DependencyProperty field, thus defining a dependency property. When you define your
own properties and want them to support many aspects of Windows Presentation
Foundation (WPF) functionality, including styles, data binding, inheritance, animation,
and default values, you should implement them as a dependency property.
Example
The following example first registers a dependency property by calling the Register
method. The name of the identifier field that you use to store the name and
characteristics of the dependency property must be the Name you chose for the
dependency property as part of the Register call, appended by the literal string
Property . For instance, if you register a dependency property with a Name of Location ,
then the identifier field that you define for the dependency property must be named
LocationProperty .
In this example, the name of the dependency property and its CLR accessor is State ; the
identifier field is StateProperty ; the type of the property is Boolean; and the type that
registers the dependency property is MyStateControl .
If you fail to follow this naming pattern, designers might not report your property
correctly, and certain aspects of property system style application might not behave as
expected.
You can also specify default metadata for a dependency property. This example registers
the default value of the State dependency property to be false .
C#
For more information about how and why to implement a dependency property, as
opposed to just backing a CLR property with a private field, see Dependency Properties
Overview.
See also
Dependency Properties Overview
How-to Topics
How to: Add an Owner Type for a
Dependency Property
Article • 02/06/2023
Without wrappers, the dependency property would still work from the perspective of
programmatic access using GetValue or SetValue. But you typically want to parallel this
property-system behavior with the CLR property wrappers. The wrappers make it easier
to set the dependency property programmatically, and make it possible to set the
properties as XAML attributes.
To find out how to override default metadata, see Override Metadata for a Dependency
Property.
Example
C#
See also
Custom Dependency Properties
Dependency Properties Overview
How to: Register an Attached Property
Article • 08/10/2023
This example shows how to register an attached property and provide public accessors
so that you can use the property in both XAML and code. Attached properties are a
syntax concept defined by XAML. Most attached properties for WPF types are also
implemented as dependency properties. You can use dependency properties on any
DependencyObject types.
Example
The following example shows how to register an attached property as a dependency
property, by using the RegisterAttached method. The provider class has the option of
providing default metadata for the property that is applicable when the property is used
on another class, unless that class overrides the metadata. In this example, the default
value of the IsBubbleSource property is set to false .
The provider class for an attached property (even if it is not registered as a dependency
property) must provide static get and set accessors that follow the naming convention
Set [AttachedPropertyName] and Get [AttachedPropertyName]. These accessors are
required so that the acting XAML reader can recognize the property as an attribute in
XAML and resolve the appropriate types.
C#
See also
DependencyProperty
Dependency Properties Overview
Custom Dependency Properties
How-to Topics
How to: Override Metadata for a
Dependency Property
Article • 06/02/2023
This example shows how to override default dependency property metadata that comes
from an inherited class, by calling the OverrideMetadata method and providing type-
specific metadata.
Example
By defining its PropertyMetadata, a class can define the dependency property's
behaviors, such as its default value and property system callbacks. Many dependency
property classes already have default metadata established as part of their registration
process. This includes the dependency properties that are part of the WPF API. A class
that inherits the dependency property through its class inheritance can override the
original metadata so that the characteristics of the property that can be altered through
metadata will match any subclass-specific requirements.
C#
C#
MyStateControl.StateProperty.OverrideMetadata(typeof(MyAdvancedStateControl)
, new PropertyMetadata(true));
}
}
See also
DependencyProperty
Dependency Properties Overview
Custom Dependency Properties
How-to Topics
Events (WPF)
Article • 02/06/2023
Windows Presentation Foundation (WPF) introduces routed events that can invoke
handlers that exist on various listeners in the element tree of an application.
In This Section
Routed Events Overview
Attached Events Overview
Object Lifetime Events
Marking Routed Events as Handled, and Class Handling
Preview Events
Property Change Events
Visual Basic and WPF Event Handling
Weak Event Patterns
How-to Topics
Reference
RoutedEvent
EventManager
RoutingStrategy
Related Sections
WPF Architecture
XAML in WPF
Base Elements
Element Tree and Serialization
Properties
Input
Resources
Styling and Templating
WPF Content Model
Threading Model
Routed Events Overview
Article • 03/17/2022
This topic describes the concept of routed events in Windows Presentation Foundation
(WPF). The topic defines routed events terminology, describes how routed events are
routed through a tree of elements, summarizes how you handle routed events, and
introduces how to create your own custom routed events.
Prerequisites
This topic assumes that you have basic knowledge of the common language runtime
(CLR) and object-oriented programming, as well as the concept of how the relationships
between WPF elements can be conceptualized as a tree. In order to follow the examples
in this topic, you should also understand WPF applications or pages. For more
information, see Walkthrough: My first WPF desktop application and XAML in WPF.
Functional definition: A routed event is a type of event that can invoke handlers on
multiple listeners in an element tree, rather than just on the object that raised the event.
A typical WPF application contains many elements. Whether created in code or declared
in XAML, these elements exist in an element tree relationship to each other. The event
route can travel in one of two directions depending on the event definition, but
generally the route travels from the source element and then "bubbles" upward through
the element tree until it reaches the element tree root (typically a page or a window).
This bubbling concept might be familiar to you if you have worked with the DHTML
object model previously.
XAML
<Border Height="50" Width="300" BorderBrush="Gray" BorderThickness="1">
<StackPanel Background="LightGray" Orientation="Horizontal"
Button.Click="CommonClickHandler">
<Button Name="YesButton" Width="Auto" >Yes</Button>
<Button Name="NoButton" Width="Auto" >No</Button>
<Button Name="CancelButton" Width="Auto" >Cancel</Button>
</StackPanel>
</Border>
In this simplified element tree, the source of a Click event is one of the Button elements,
and whichever Button was clicked is the first element that has the opportunity to handle
the event. But if no handler attached to the Button acts on the event, then the event will
bubble upwards to the Button parent in the element tree, which is the StackPanel.
Potentially, the event bubbles to Border, and then beyond to the page root of the
element tree (not shown).
In other words, the event route for this Click event is:
Button-->StackPanel-->Border-->...
Control composition and encapsulation: Various controls in WPF have a rich content
model. For example, you can place an image inside of a Button, which effectively
extends the visual tree of the button. However, the added image must not break the hit-
testing behavior that causes a button to respond to a Click of its content, even if the
user clicks on pixels that are technically part of the image.
Singular handler attachment points: In Windows Forms, you would have to attach the
same handler multiple times to process events that could be raised from multiple
elements. Routed events enable you to attach that handler only once, as was shown in
the previous example, and use handler logic to determine where the event came from if
necessary. For instance, this might be the handler for the previously shown XAML:
C#
private void CommonClickHandler(object sender, RoutedEventArgs e)
{
FrameworkElement feSource = e.Source as FrameworkElement;
switch (feSource.Name)
{
case "YesButton":
// do something here ...
break;
case "NoButton":
// do something ...
break;
case "CancelButton":
// do something ...
break;
}
e.Handled=true;
}
Class handling: Routed events permit a static handler that is defined by the class. This
class handler has the opportunity to handle an event before any attached instance
handlers can.
Referencing an event without reflection: Certain code and markup techniques require a
way to identify a specific event. A routed event creates a RoutedEvent field as an
identifier, which provides a robust event identification technique that does not require
static or run-time reflection.
The following example shows the declaration for a custom Tap routed event, including
the registration and exposure of the RoutedEvent identifier field and the add and
remove implementations for the Tap CLR event.
C#
XAML
<Button Click="b1SetColor">button</Button>
The XAML syntax for adding standard CLR event handlers is the same for adding routed
event handlers, because you are really adding handlers to the CLR event wrapper, which
has a routed event implementation underneath. For more information about adding
event handlers in XAML, see XAML in WPF.
Routing Strategies
Routed events use one of three routing strategies:
Bubbling: Event handlers on the event source are invoked. The routed event then
routes to successive parent elements until reaching the element tree root. Most
routed events use the bubbling routing strategy. Bubbling routed events are
generally used to report input or state changes from distinct controls or other UI
elements.
Direct: Only the source element itself is given the opportunity to invoke handlers
in response. This is analogous to the "routing" that Windows Forms uses for
events. However, unlike a standard CLR event, direct routed events support class
handling (class handling is explained in an upcoming section) and can be used by
EventSetter and EventTrigger.
Tunneling: Initially, event handlers at the element tree root are invoked. The routed
event then travels a route through successive child elements along the route,
towards the node element that is the routed event source (the element that raised
the routed event). Tunneling routed events are often used or handled as part of
the compositing for a control, such that events from composite parts can be
deliberately suppressed or replaced by events that are specific to the complete
control. Input events provided in WPF often come implemented as a
tunneling/bubbling pair. Tunneling events are also sometimes referred to as
Preview events, because of a naming convention that is used for the pairs.
Where routed events become powerful is if you use any of the suggested scenarios:
defining common handlers at a common root, compositing your own control, or
defining your own custom control class.
Routed event listeners and routed event sources do not need to share a common event
in their hierarchy. Any UIElement or ContentElement can be an event listener for any
routed event. Therefore, you can use the full set of routed events available throughout
the working API set as a conceptual "interface" whereby disparate elements in the
application can exchange event information. This "interface" concept for routed events
is particularly applicable for input events.
Routed events can also be used to communicate through the element tree, because the
event data for the event is perpetuated to each element in the route. One element could
change something in the event data, and that change would be available to the next
element in the route.
Other than the routing aspect, there are two other reasons that any given WPF event
might be implemented as a routed event instead of a standard CLR event. If you are
implementing your own events, you might also consider these principles:
Certain WPF styling and templating features such as EventSetter and EventTrigger
require the referenced event to be a routed event. This is the event identifier
scenario mentioned earlier.
Routed events support a class handling mechanism whereby the class can specify
static methods that have the opportunity to handle routed events before any
registered instance handlers can access them. This is very useful in control design,
because your class can enforce event-driven class behaviors that cannot be
accidentally suppressed by handling an event on an instance.
XAML
<Button Click="b1SetColor">button</Button>
b1SetColor is the name of the implemented handler that contains the code that handles
the Click event. b1SetColor must have the same signature as the RoutedEventHandler
delegate, which is the event handler delegate for the Click event. The first parameter of
all routed event handler delegates specifies the element to which the event handler is
added, and the second parameter specifies the data for the event.
C#
RoutedEventHandler is the basic routed event handler delegate. For routed events that
are specialized for certain controls or scenarios, the delegates to use for the routed
event handlers also might become more specialized, so that they can transmit
specialized event data. For instance, in a common input scenario, you might handle a
DragEnter routed event. Your handler should implement the DragEventHandler
delegate. By using the most specific delegate, you can process the DragEventArgs in the
handler and read the Data property, which contains the clipboard payload of the drag
operation.
For a complete example of how to add an event handler to an element using XAML, see
Handle a Routed Event.
C#
void MakeButton()
{
Button b2 = new Button();
b2.AddHandler(Button.ClickEvent, new RoutedEventHandler(Onb2Click));
}
void Onb2Click(object sender, RoutedEventArgs e)
{
//logic to handle the Click event
}
The next example shows the C# operator syntax (Visual Basic has slightly different
operator syntax because of its handling of dereferencing):
C#
void MakeButton2()
{
Button b2 = new Button();
b2.Click += new RoutedEventHandler(Onb2Click2);
}
void Onb2Click2(object sender, RoutedEventArgs e)
{
//logic to handle the Click event
}
For an example of how to add an event handler in code, see Add an Event Handler
Using Code.
If you are using Visual Basic, you can also use the Handles keyword to add handlers as
part of the handler declarations. For more information, see Visual Basic and WPF Event
Handling.
The Concept of Handled
All routed events share a common event data base class, RoutedEventArgs.
RoutedEventArgs defines the Handled property, which takes a Boolean value. The
purpose of the Handled property is to enable any event handler along the route to mark
the routed event as handled, by setting the value of Handled to true . After being
processed by the handler at one element along the route, the shared event data is again
reported to each listener along the route.
The value of Handled affects how a routed event is reported or processed as it travels
further along the route. If Handled is true in the event data for a routed event, then
handlers that listen for that routed event on other elements are generally no longer
invoked for that particular event instance. This is true both for handlers attached in
XAML and for handlers added by language-specific event handler attachment syntaxes
such as += or Handles . For most common handler scenarios, marking an event as
handled by setting Handled to true will "stop" routing for either a tunneling route or a
bubbling route, and also for any event that is handled at a point in the route by a class
handler.
In code, instead of using a language-specific event syntax that works for general
CLR events, call the WPF method AddHandler(RoutedEvent, Delegate, Boolean) to
add your handler. Specify the value of handledEventsToo as true .
In addition to the behavior that Handled state produces in routed events, the concept of
Handled has implications for how you should design your application and write the
event handler code. You can conceptualize Handled as being a simple protocol that is
exposed by routed events. Exactly how you use this protocol is up to you, but the
conceptual design for how the value of Handled is intended to be used is as follows:
If a routed event is marked as handled, then it does not need to be handled again
by other elements along that route.
If a routed event is not marked as handled, then other listeners that were earlier
along the route have chosen either not to register a handler, or the handlers that
were registered chose not to manipulate the event data and set Handled to true .
(Or, it is of course possible that the current listener is the first point in the route.)
Handlers on the current listener now have three possible courses of action:
Take no action at all; the event remains unhandled, and the event routes to the
next listener.
Execute code in response to the event, but make the determination that the
action taken was not substantial enough to warrant marking the event as
handled. The event routes to the next listener.
Execute code in response to the event. Mark the event as handled in the event
data passed to the handler, because the action taken was deemed substantial
enough to warrant marking as handled. The event still routes to the next
listener, but with Handled= true in its event data, so only handledEventsToo
listeners have the opportunity to invoke further handlers.
For more information about Handled, class handling of routed events, and
recommendations about when it is appropriate to mark a routed event as Handled, see
Marking Routed Events as Handled, and Class Handling.
In applications, it is quite common to just handle a bubbling routed event on the object
that raised it, and not be concerned with the event's routing characteristics at all.
However, it is still a good practice to mark the routed event as handled in the event
data, to prevent unanticipated side effects just in case an element that is further up the
element tree also has a handler attached for that same routed event.
Class Handlers
If you are defining a class that derives in some way from DependencyObject, you can
also define and attach a class handler for a routed event that is a declared or inherited
event member of your class. Class handlers are invoked before any instance listener
handlers that are attached to an instance of that class, whenever a routed event reaches
an element instance in its route.
Some WPF controls have inherent class handling for certain routed events. This might
give the outward appearance that the routed event is not ever raised, but in reality it is
being class handled, and the routed event can potentially still be handled by your
instance handlers if you use certain techniques. Also, many base classes and controls
expose virtual methods that can be used to override class handling behavior. For more
information both on how to work around undesired class handling and on defining your
own class handling in a custom class, see Marking Routed Events as Handled, and Class
Handling.
The WPF input system uses attached events extensively. However, nearly all of these
attached events are forwarded through base elements. The input events then appear as
equivalent non-attached routed events that are members of the base element class. For
instance, the underlying attached event Mouse.MouseDown can more easily be handled
on any given UIElement by using MouseDown on that UIElement rather than dealing
with attached event syntax either in XAML or code.
For more information about attached events in WPF, see Attached Events Overview.
XAML
Here, the parent element listener where the handler is added is a StackPanel. However, it
is adding a handler for a routed event that was declared and will be raised by the Button
class (ButtonBase actually, but available to Button through inheritance). Button "owns"
the event, but the routed event system permits handlers for any routed event to be
attached to any UIElement or ContentElement instance listener that could otherwise
attach listeners for a common language runtime (CLR) event. The default xmlns
namespace for these qualified event attribute names is typically the default WPF xmlns
namespace, but you can also specify prefixed namespaces for custom routed events. For
more information about xmlns, see XAML Namespaces and Namespace Mapping for
WPF XAML.
WPF input events that come in pairs are implemented so that a single user action from
input, such as a mouse button press, will raise both routed events of the pair in
sequence. First, the tunneling event is raised and travels its route. Then the bubbling
event is raised and travels its route. The two events literally share the same event data
instance, because the RaiseEvent method call in the implementing class that raises the
bubbling event listens for the event data from the tunneling event and reuses it in the
new raised event. Listeners with handlers for the tunneling event have the first
opportunity to mark the routed event handled (class handlers first, then instance
handlers). If an element along the tunneling route marked the routed event as handled,
the already-handled event data is sent on for the bubbling event, and typical handlers
attached for the equivalent bubbling input events will not be invoked. To outward
appearances it will be as if the handled bubbling event has not even been raised. This
handling behavior is useful for control compositing, where you might want all hit-test
based input events or focus-based input events to be reported by your final control,
rather than its composite parts. The final control element is closer to the root in the
compositing, and therefore has the opportunity to class handle the tunneling event first
and perhaps to "replace" that routed event with a more control-specific event, as part of
the code that backs the control class.
As an illustration of how input event processing works, consider the following input
event example. In the following tree illustration, leaf element #2 is the source of both a
PreviewMouseDown and then a MouseDown event:
A routed event handler delegate provides references to two objects: the object that
raised the event and the object where the handler was invoked. The object where the
handler was invoked is the object reported by the sender parameter. The object where
the event was first raised is reported by the Source property in the event data. A routed
event can still be raised and handled by the same object, in which case sender and
Source are identical (this is the case with Steps 3 and 4 in the event processing example
list).
Because of tunneling and bubbling, parent elements receive input events where the
Source is one of their child elements. When it is important to know what the source
element is, you can identify the source element by accessing the Source property.
Usually, once the input event is marked Handled, further handlers are not invoked.
Typically, you should mark input events as handled as soon as a handler is invoked that
addresses your application-specific logical handling of the meaning of the input event.
The exception to this general statement about Handled state is that input event
handlers that are registered to deliberately ignore Handled state of the event data
would still be invoked along either route. For more information, see Preview Events or
Marking Routed Events as Handled, and Class Handling.
The shared event data model between tunneling and bubbling events, and the
sequential raising of first tunneling then bubbling events, is not a concept that is
generally true for all routed events. That behavior is specifically implemented by how
WPF input devices choose to raise and connect the input event pairs. Implementing
your own input events is an advanced scenario, but you might choose to follow that
model for your own input events also.
Certain classes choose to class-handle certain input events, usually with the intent of
redefining what a particular user-driven input event means within that control and
raising a new event. For more information, see Marking Routed Events as Handled, and
Class Handling.
For more information on input and how input and events interact in typical application
scenarios, see Input Overview.
XAML
<StackPanel
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.EventOvw2"
Name="dpanel2"
Initialized="PrimeHandledToo"
>
<StackPanel.Resources>
<Style TargetType="{x:Type Button}">
<EventSetter Event="Click" Handler="b1SetColor"/>
</Style>
</StackPanel.Resources>
<Button>Click me</Button>
<Button Name="ThisButton" Click="HandleThis">
Raise event, handle it, use handled=true handler to get it anyway.
</Button>
</StackPanel>
The advantage gained here is that the style is likely to contain a great deal of other
information that could apply to any button in your application, and having the
EventSetter be part of that style promotes code reuse even at the markup level. Also, an
EventSetter abstracts method names for handlers one step further away from the
general application and page markup.
Another specialized syntax that combines the routed event and animation features of
WPF is an EventTrigger. As with EventSetter, only routed events may be used for an
EventTrigger. Typically, an EventTrigger is declared as part of a style, but an EventTrigger
can also be declared on page-level elements as part of the Triggers collection, or in a
ControlTemplate. An EventTrigger enables you to specify a Storyboard that runs
whenever a routed event reaches an element in its route that declares an EventTrigger
for that event. The advantage of an EventTrigger over just handling the event and
c