Printing support is yet a missing feature in Silverlight 3. This article won’t fix that. But it will give an example for a workaround that combines two tasks. First to generate an output file in a visually customized and printable format. Second the opportunity to save the data in a reusable format using XML. In the following example we are going to build the engine for an application that enables the user to manage different lawyers organized respective there branch of law. The snippets are creating an XML file that is styled inline using CSS and that can be opened in every browser. The XML file then can be printed by the user using the print dialog of the browser. The XML file itself will be saved in the file system of the user.
The logical XML structure
At first we need to create the logical structure of our XML data. Throughout this example I will use the following simple XML structure:
<?xml version="1.0" encoding="utf-8"?>
<lawyers>
<lawyer>
<id>
<label></label>
<value></value>
</id>
<name>
<label></label>
<value></value>
</name>
<branchoflaw>
<label></label>
<value></value>
</branchoflaw>
</lawyer>
</lawyers>
Every lawyer has an id, a name and a branch of law. The elements <id>, <name> and <branchoflaw> each have the two child elements <label> and <value>. The values of the <label> elements are holding the display text for the visual representation of the XML data in the browser. The values of the <value> elements are holding the created and stored XML data respectively.
The Project
Start building a new Silverlight 3 project using Expression Blend 3 or Visual Studio 2008 SP1. Add a reference to the System.Xml and the System.Xml.Linq assemblies. Then insert the following imports statements:
Imports System.Xml.Linq
Imports System.IO
With the System.Xml.Linq namespace we build the logical xml data. The System.IO namespace we are going to use for the save file and open file actions.
In MainPage.xaml we need a Button and call it x:Name="btSave".
In MainPage.xaml.vb we declare a private member variable called xdoc that will hold the generated XML data.
Private xdoc As XDocument
Private Sub MainPage_Loaded( _
ByVal sender As Object, _
ByVal e As System.Windows.RoutedEventArgs) _
Handles Me.Loaded
xdoc = New XDocument
End Sub
In the Click event handler of btSave we are calling two sub routines.
Private Sub btSave_Click( _
ByVal sender As Object, _
ByVal e As System.Windows.RoutedEventArgs) _
Handles btSave.Click
BuildXml()
SaveXMLFile()
End Sub
Creating XDocument with XML literals
We build the Private Sub routine called BuildXml() where we are going to create the XML structure. In there we are using the technique to create XDocument with XML literals:
Private Sub BuildXml()
Dim xdoc As XDocument
xdoc = <?xml version="1.0" encoding="utf-8"?>
<lawyers>
<lawyer>
<id>
<label></label>
<value></value>
</id>
<name>
<label></label>
<value></value>
</name>
<branchoflaw>
<label></label>
<value></value>
</branchoflaw>
</lawyer>
</lawyers>
End Sub
If we create a XML file with the above logical structure and open it in the browser it looks like this:

If we would watch the XML file in the print preview of the browser it would exactly look the same. But we want that it (with sample data) looks like this in the browser and in the print preview of the browser respectively:

To achieve this we have to add some code to the BuildXml() routine.
Creating the style for the XML in code behind
First we have to add a processing instruction into the XML code:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" h ref="#DataViewStyle" ?>
<lawyers>
...
The href–attribute in the above processing instruction is pointing to the id –attribute of a XML element that we are creating in the next step to define the CSS layout style:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" h ref="#DataViewStyle" ?>
<lawyers>
<viewstyle id="DataViewStyle">
...
Within the XML element we called <viewstyle> we now simply write the CSS layout for our logical XML structure. Here you can create the CSS style of your choice to customize the look and feel of your visually desired XML output. For the above screenshot example the CSS in the <viewstyle> element is the following:
<viewstyle id="DataViewStyle">
lawyer {
display:block;
margin-top:20px;
margin-bottom:8px;
margin-left:16px;
font-size:14px;
border-style:solid;
border-color:#003366;
border-width:1px;
padding-left:20px;
padding-top:8px;
padding-bottom:8px
}
id {
display:block;
margin-top:8px;
margin-bottom:8px;
color:#3366CC;
font-weight:bolder;
}
idlabel {
display:inline-block;
position:absolute;
font-weight:bolder;
min-width:220px;
}
idvalue {
display:inline-block;
position:relative;
left:140px;
}
name, branchoflaw {
display:block;
margin-top:8px;
margin-bottom:8px;
}
label {
display:inline-block;
position:absolute;
font-weight:bolder;
min-width:220px;
}
value {
display:inline-block;
position:relative;
left:140px;
}
viewstyle {display:none}
</viewstyle>
Note the CSS layout instruction at the end of the CSS code for the <viewstyle> element itself:
<viewstyle id="DataViewStyle">
...
viewstyle {display:none}
</viewstyle>
This is important to avoid displaying the <viewstyle> element itself in the visual and printable output. This line of CSS code has to be placed at the very end of your CSS code.
XML data input
There are many techniques to fill the XML file with your data objects. You can use e.g. the following to fill your XML file with values from your Data Objects.
We define a class for our Lawyer objects:
Public Class Lawyer
Sub New()
' nix tun
End Sub
Public Sub New(ByVal id As Integer, _
ByVal name As String, _
ByVal branchoflaw As String)
Me._id = id
Me._name = name
Me._branchoflaw = branchoflaw
End Sub
Private _id As Integer
Private _name As String
Private _branchoflaw As String
Public ReadOnly Property ID() As Integer
Get
Return _id
End Get
End Property
Public ReadOnly Property Name() As String
Get
Return _name
End Get
End Property
Public ReadOnly Property BranchOfLaw() As String
Get
Return _branchoflaw
End Get
End Property
End Class
Using some of this Lawyer objects we build some data in code behind and as a result of our work the BuildXml() routine finally has the following code:
Private Sub BuildXml()
Dim lawyerlist As List(Of Lawyer)
lawyerlist = New List(Of Lawyer)
With lawyerlist
.Add(New Lawyer(1, _
"Michael R.A. Miller", "patent law"))
.Add(New Lawyer(2, _
"Josefine Radcliff", "mercantile law"))
.Add(New Lawyer(3, _
"Jim Johnson", "law of torts"))
End With
For Each item As Lawyer In lawyerlist
Select Case item.ID
Case Is = 1
xdoc = _
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css"
h ref="#DataViewStyle" ?>
<lawyers>
<viewstyle id="DataViewStyle">
lawyer {
display:block;
margin-top:20px;
margin-bottom:8px;
margin-left:16px;
font-size:14px;
border-style:solid;
border-color:#003366;
border-width:1px;
padding-left:20px;
padding-top:8px;
padding-bottom:8px
}
id {
display:block;
margin-top:8px;
margin-bottom:8px;
color:#3366CC;
font-weight:bolder;
}
idlabel {
display:inline-block;
position:absolute;
font-weight:bolder;
min-width:220px;
}
idvalue {
display:inline-block;
position:relative;
left:140px;
}
name, branchoflaw {
display:block;
margin-top:8px;
margin-bottom:8px;
}
label {
display:inline-block;
position:absolute;
font-weight:bolder;
min-width:220px;
}
value {
display:inline-block;
position:relative;
left:140px;
}
viewstyle {display:none}
</viewstyle>
<lawyer>
<id>
<label>ID:</label>
<value><%= item.ID.ToString %></value>
</id>
<name>
<label>Name:</label>
<value><%= item.Name %></value>
</name>
<branchoflaw>
<label>Branch of Law:</label>
<value><%= item.BranchOfLaw %></value>
</branchoflaw>
</lawyer>
</lawyers>
Case Else
xdoc.<lawyers>(0).Add( _
<lawyer>
<id>
<label>ID:</label>
<value><%= item.ID.ToString %></value>
</id>
<name>
<label>Name:</label>
<value><%= item.Name %></value>
</name>
<branchoflaw>
<label>Branch of Law:</label>
<value><%= item.BranchOfLaw %></value>
</branchoflaw>
</lawyer>)
End Select
Next
End Sub
Save the XML file
Finally we need to save the XML file using the SaveFileDialog and StreamWriter. Here is the code:
Private Sub SaveXMLFile()
Dim sDialog As New SaveFileDialog
sDialog.Filter = "Xml files (*.xml)|*.xml"
If sDialog.ShowDialog = True Then
Using xstream As Stream = sDialog.OpenFile
Using xwriter As New StreamWriter(xstream)
xwriter.Write(xdoc)
End Using
End Using
End If
End Sub
The resulting visual
And this is how the XML file looks in the browser. The look and feel in the print preview of the browser is exactly the same.

Last words
This workaround has several advantages.
1. You are working with pure XML which enables you to use the entire power of LINQ to XML to create and manipulate your data including querying.
2. Using CSS you have a powerful language to design customized solutions for the visual output.
3. The created XML file has its style inline which means that you don’t need a separate file for the style. Maybe this is the biggest advantage of this workaround. If the style would be in a separate file one would never know at runtime where in the file system the user saved his XML file and the file for the style respectively. But one would need this knowledge to get/set a reference to the style.
Using the OpenFileDialog you are able to write code for runtime actions of users data manipulations.
That’s it. I hope this was useful to bridge the time until Silverlight 4 will be released with printing support. Best regards,
M. (SilverLaw)