XAML offers other advantages that
can be taken in completely different scenarios; one of these is
serialization. The System.Xaml.dll assembly implements the System.Xaml namespace that offers the XamlServices
class whose purpose is providing members for reading and writing XAML
in serialization scenarios. Because XAML is substantially Xml code that
adheres to specific schemas, serialization output will be under Xml
format. The good news is that you are not limited in using XAML
serialization only in WPF applications. You simply need to add a
reference to System.Xaml.dll. To understand how it works, create a new
console project with
Visual Basic and add the required reference. The goal of the code
example is to understand how entire objects’ graphs can be serialized
with this technique. Consider the following implementation of the Person class:
Public Class Person
Public Property FirstName As String
Public Property LastName As String
Public Property Age As Integer
Public Property Friends As List(Of Person)
End Class
Other than the usual properties, it exposes a Friends property of type List(Of Person). This enables creating a simple object graph. Now consider the following code that creates two instances of the Person class that populates the Friends property of the main Person instance that we serialize:
Dim oneFriend As New Person With {.LastName = "White",
.FirstName = "Robert", .Age = 35}
Dim anotherFriend As New Person With {.LastName = "Red",
.FirstName = "Stephen", .Age = 42}
Dim p As New Person With {.LastName = "Del Sole", .FirstName = "Alessandro",
.Age = 32,
.Friends = New List(Of Person) _
From {oneFriend, anotherFriend}}
Using objects and
collection initializers makes this operation straightforward. To
serialize an object graph, you simply invoke the XamlServices.Save shared method that requires an output stream and the object to be serialized. The following code snippet demonstrates this:
Imports System.IO, System.Xaml
'...
Using target As New FileStream("C:\Temp\Person.xaml", FileMode.Create)
XamlServices.Save(target, p)
End Using
When you serialize generic collections, especially custom ones, ensure that they implement the IList or IDictionary interfaces or the serialization process might not work correctly.
|
The previously described serialization process produces the following output:
<Person Age="32"
FirstName="Alessandro"
LastName="Del Sole"
xmlns="clr-namespace:XamlSerialization;assembly=XamlSerialization"
xmlns:scg="clr-namespace:System.Collections.Generic;
assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Person.Friends>
<scg:List x:TypeArguments="Person" Capacity="4">
<Person Friends="{x:Null}" Age="35" FirstName="Robert"
LastName="White" />
<Person Friends="{x:Null}" Age="42" FirstName="Stephen"
LastName="Red" />
</scg:List>
</Person.Friends>
</Person>
This technique is efficient and makes output readable. As usual in Xaml files, the Xaml schema is pointed to via the x namespace. Notice how the scg namespace points to the System.Collections.Generic .NET namespace, required for deserializing the content as a generic collection. Also notice how the Person.Friends element defines subsequent Person elements storing information on child Person classes being part of the Friends property. Finally, notice how the Friends property for nested Person
elements is null. (We did not define child elements for the property.)
Deserializing such content is also straightforward. To accomplish this
you simply invoke the XamlServices.Load
shared method converting its result into the appropriate type. The
following code shows how deserialization works, iterating the final
result for demonstrating that deserialization was correctly performed:
Using source As New FileStream("C:\temp\person.xaml", FileMode.Open)
Dim result As Person = CType(XamlServices.Load(source), Person)
'Shows:
'White
'Green
For Each p In result.Friends
Console.WriteLine(p.LastName)
Next
Console.ReadLine()
End Using
XAML serialization can be used
in different situations, such as persisting the state of WPF controls
but also serializing entire .NET objects graphs.