Search code examples
c#.netwpfflowdocumentxps

Exception while rendering XpsDocument after conversion from FlowDocument


I'm developing an application that heavily uses the conversion from a FlowDocument to a XpsDocument. From time to time an exception is thrown: NotSupportedException: "The URI prefix is not recognized."

My scenario is very complex and I condensed it to a simple test. If you type in some characters in the text box (fast), you'll get the exception immediately.

Xaml:

<Window x:Class="FlowDocPreview.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <RichTextBox Name="rtb" KeyUp="rtb_KeyUp" />
        <DocumentViewer Grid.Column="1" Name="dv" />
    </Grid>
</Window>

Code behind:

using System;
using System.IO;
using System.IO.Packaging;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Xps;
using System.Windows.Xps.Packaging;


namespace FlowDocPreview
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            rtb.Document = new FlowDocument();
        }

        Uri _packageUri = null;

        private void rtb_KeyUp(object sender, KeyEventArgs e)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                dv.Document = null;
                if (_packageUri != null)
                {
                    PackageStore.RemovePackage(_packageUri);
                }

                _packageUri = new Uri("memorystream://" + DateTime.Now.Ticks + ".xps");

                TextRange sourceContent = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd);
                MemoryStream stream = new MemoryStream();
                sourceContent.Save(stream, DataFormats.Xaml);
                FlowDocument flowDocumentCopy = new FlowDocument();
                TextRange copyDocumentRange = new TextRange(flowDocumentCopy.ContentStart, flowDocumentCopy.ContentEnd);
                copyDocumentRange.Load(stream, DataFormats.Xaml);

                Package package = Package.Open(ms, FileMode.OpenOrCreate, FileAccess.ReadWrite);
                PackageStore.AddPackage(_packageUri, package);
                XpsDocument xpsDoc = new XpsDocument(package, CompressionOption.SuperFast);
                xpsDoc.Uri = _packageUri;
                XpsDocumentWriter documentWriter = XpsDocument.CreateXpsDocumentWriter(xpsDoc);
                documentWriter.Write(((IDocumentPaginatorSource)flowDocumentCopy).DocumentPaginator);

                dv.Document = xpsDoc.GetFixedDocumentSequence();
            }
        }
    }
}

That exception cannot be catched (refer to https://social.msdn.microsoft.com/Forums/windows/en-US/431e8e80-3bf0-4679-a0c0-9b5cae4f2f38/systemnotsupportexception-the-uri-prefix-is-not-recognized-when-creating-xps-document?forum=netfxbcl ) or prevented in advance (the package seems to be existing correctly). I examined the .net code and found no reason for that strange behaviour. In total I've spent day or even weeks to find a fix.

Any ideas? Regards, Heady


Solution

  • Finally I got a bearable solution. The problem was that my WPF Application did not catch (any?) unhandled exceptions. I start my Application in code and in the xaml file I had registered the DispatcherUnhandledException handler. Anyway it did not catch. Perhaps there is some additional steps ro initialize an application before running it. I added the DispatcherUnhandledException handler in code, now it works for me. I can't avoid the exception itself, but at least I can handle it.

    Regards, Headi