Running on Empty

The few things I know, I like to share.

Using FlowDocuments XAML to print XPS Documents. (Part 6)

Indroduction

This one is for you Linda and Cow-Killer.

Welcome to Part 6 of the Using FlowDocuments XAML to print XPS Documents series.  Up until now it has been impossible to use this series to create an XPS document file or display the XAML text in a document viewer.  It would be nice to be able to create a XAML template and easily insert text into the template using databinding.  Here is my solution, hope to hear your feedback.

Creating a new method to Load Xaml Strings

This method simply takes a raw XAML string and loads it into a FlowDocument, you may have seen this before in previous samples.

        public static IDocumentPaginatorSource RenderFlowDocumentTemplate(string templatePath, 

Dictionary<string, string> parameters)
        {
            string rawXamlText = "";
            using (StreamReader streamReader = File.OpenText(templatePath))
            {
                rawXamlText = streamReader.ReadToEnd();
            }

            rawXamlText = MergeParameters(parameters, rawXamlText);

            FlowDocument document = XamlReader.Load(new XmlTextReader(new StringReader(rawXamlText))) as 

FlowDocument;
           
            return document;
        }

The new parts of this method are the addition of a Dictionary of string key/value pairs and the MergeParameters method.

Merging Parameters

Since XAML is nothing more than a jazzed up XML file, we can use simple string replacements to replace items in our template with strings from our objects.

        private static string MergeParameters(Dictionary<string, string> parameters, string template)
        {
            foreach (KeyValuePair<string, string> kvp in parameters)
            {
                template = template.Replace(string.Format("[{0}]", kvp.Key), kvp.Value);
            }
            return template;
        }

Now we have a nearly completed solution to XAML template rendering, all that is left to do is create a template.

The new XAML Template

<FlowDocument xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
     xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml>
    <Paragraph FontFamily="Arial" Margin="20">
        <TextBlock Text="&#91;TestString&#93;" FontSize="12"/>
    </Paragraph>
</FlowDocument>

Notice the inclusion of [TestString], this is essentially the “databind” we will use in the string Key/Value pair dictionary.

Using the new Key/Value pair databinding

            Dictionary<string, string> strings = new Dictionary<string,string>();
            strings.Add("TestString", "Tester");
            IDocumentPaginatorSource flowDocument =
                

XamlTemplatePrinter.RenderFlowDocumentTemplate(Path.Combine(Environment.CurrentDirectory, 

"TestTemplate.xaml"), strings);
            flowDocument.DocumentPaginator.PageSize = new Size(96 * 8.5, 96 * 11);
            PrintDialog flowPrintDialog = XamlTemplatePrinter.GetPrintDialog();
            if (flowPrintDialog == null)
                return;
            PrintQueue flowPrintQueue = flowPrintDialog.PrintQueue;
            XamlTemplatePrinter.PrintFlowDocument(flowPrintQueue, 

flowDocument.DocumentPaginator);

Conclusion

Thank you all for your comments and suggestions.  Your questions and comments are fuel for the continued success of this blog.  Please feel free to leave a comment or contact me if you have suggestions or questions.

May 28, 2008 Posted by | C#, WPF, XAML, XPS | 15 Comments