' Create the Button.
Dim originalButton As New Button()
originalButton.Height = 50
originalButton.Width = 100
originalButton.Background = Brushes.AliceBlue
originalButton.Content = "Click Me"
' Save the Button to a string.
Dim savedButton As String = XamlWriter.Save(originalButton)
' Load the button
Dim stringReader As New StringReader(savedButton)
Dim xmlReader As XmlReader = XmlReader.Create(stringReader)
Dim readerLoadButton As Button = CType(XamlReader.Load(xmlReader), Button)
The synchronous
Load
methods are static, but the asynchronous
LoadAsync
methods are not static and require an instance of the
XamlReader
class to use.
The output of the
Load
methods is a single object, which represents the root object of a created object tree or object graph. Object graphs that are created by
XamlReader
are typically added to the existing object tree of a WPF application at run time. Otherwise the new object graph is considered disconnected for purposes of the WPF application model. This means that it does not render, and cannot be accessed using any of the object tree techniques as applied to the WPF application's main object tree (for example, the APIs
FindName
,
LogicalTreeHelper
,
VisualTreeHelper
). For more information on object tree concepts, see
Trees in WPF
.
XamlReader
supports the following primary scenarios:
Cloning/object factory
: Without additional mechanisms, a reference type generally cannot be included in more than one position in a WPF object tree. (Examples of additional mechanisms that offer support for sharing or re-use in WPF include objects that are based on
Freezable
, or support for commonly shareable objects such as
Brush
that are referenced as an item from a
ResourceDictionary
.) One way to clone an object that is already in the object tree is to serialize the object using
XamlWriter.Save
. You then use the serialized string as input for a call to
Load
, with a stream or
XmlReader
as an intermediary.
Constructing objects based on just-in-time information
: There are often other ways to have late-binding or user-supplied input change the state of existing objects. For example you could use the same value to set more than one property, or use data binding. But if you have a scenario where even the type of object to create is only determinable at run time or with user interaction, then creating such an object by building up a string for
Load
input is often a useful technique.
Using existing resource techniques
: The
Stream
type is used frequently in other frameworks or technologies for transferring data or objects across application boundaries or for similar situations. You can then use the
Stream
techniques to store or obtain XAML-formatted data that you eventually use to create an object as part of your application.
Fixed documents:
Your application might load local or downloaded XPS documents for inclusion in a WPF application object tree and UI.
This documentation sometimes describes an object graph, as opposed to an object tree. A strict parent-child relationship does not always exist in the run time object relationships of a run time WPF application, so an object graph is a more widely applicable terminology. However, because WPF also includes two different tree conceptualization APIs (
LogicalTreeHelper
,
VisualTreeHelper
) the tree metaphor still applies adequately to most real-world cases in WPF. From the XAML language perspective however, the object graph is often the best way to think about how objects are created out of XAML, because the XAML language itself does not necessarily specify helper class methodologies that bring the relationships more into a tree structure again.
Code Access Security, Loose XAML, and XamlReader
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.
WPF supports the .NET security framework Code Access Security (CAS). This means that WPF content running in the internet zone has reduced execution permissions. "Loose XAML" (pages of noncompiled XAML interpreted at load time by a XAML viewer) and XAML browser application (XBAP) are usually run in this internet zone and use the same permission set. However, XAML loaded in to a fully trusted application has the same access to the system resources as the hosting application does. For more information, see
WPF Partial Trust Security
.
The implications of these statements for
XamlReader
is that your application design must make trust decisions about the XAML you decide to load. If you are loading XAML that is not trusted, consider implementing your own sandboxing technique for how you load the resulting object graph.
XamlReader
can also be called by partial trust code. In this case, Internet security zone is applied for code access security. If anything in the loaded XAML is invalid under Internet security zone, a XAML parse exception is thrown. Under XBAP and other cases that are partial trust at the platform level, where
XamlReader
is part of the execution, you get the same exception behavior as with explicit partial trust calls.
WPF XAML, XAML Readers/Writers, and XAML Language Versioning
XAML2009 includes language features such as
x:Reference
and
x:FactoryMethod
. You can use signatures of
Load
or
Parse
to load XAML that uses these features. However, those language features are not supported for XAML that needs to be markup compiled (such as XAML for the
Page
build action in a WPF application, or any XAML that involves the markup compile task in the build actions).
WPF types and the WPF technology in general support concepts that rely on access to WPF internals. For instance, how WPF implements dependency properties relies on internal techniques for efficient type-member lookup. Access to these internals is enabled by the XAML reading and writing APIs provided in
XamlWriter
and
XamlReader
from the
System.Windows.Markup
namespace and PresentationFramework assembly. However, the lower-level XAML readers and XAML writers from the System.Xaml assembly (classes based on
System.Xaml.XamlReader
,
System.Xaml.XamlWriter
) do not have access to the WPF internals. There is no dependency from System.Xaml to any WPF-specific assembly. Without access to the WPF internals, System.Xaml readers and writers cannot correctly load or save all WPF types, or types based on WPF types. In particular, the System.Xaml readers and writers do not understand concepts such as the WPF dependency property backing property store, or all the specifics of how WPF uses styles, resource dictionaries and templates. Therefore you have a choice to make:
If you are loading WPF types, and/or you are using XAML in BAML form in any way, use the PresentationFramework XAML readers and XAML writers.
If you are not relying on any WPF types or the BAML form of XAML, and are not using another specific technology's XAML reader or XAML writer implementation for reasons that are specific to that framework, use the System.Xaml XAML readers and XAML writers.
System.Xaml Backing Implementation in .NET 4
XamlReader
is the callable API surface for the WPF framework-level XAML parser. The same underlying XAML parser also performs the run-time XAML loading and parsing for WPF applications that target .NET Framework 3.0 and .NET Framework 3.5.
If you are targeting .NET Framework 4, the external API is the same, but parts of the implementation are built on the .NET Framework 4 general XAML implementation in the System.Xaml assembly, which improves many of the technical and reporting aspects of parsing XAML. Targeting .NET Framework 4 necessarily entails including System.Xaml as a reference, and details of implementation such as the exceptions reported may come from System.Xaml defined types.
Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see:
https://aka.ms/ContentUserFeedback
.
Submit and view feedback for
This product