要的DocumentViewer RichTextBox的绑定错误 [英] DocumentViewer to RichTextBox Binding Error

查看:319
本文介绍了要的DocumentViewer RichTextBox的绑定错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有RichTextBox中和的DocumentViewer(放置在一个TabControl)的应用程序,我想做出类似的热preVIEW。我已经绑定 DocumentViewer.Document 属性 RichTextBox.Document

I have an application with RichTextBox and DocumentViewer (placed in a TabControl), and I want to make something like "hot preview". I've binded DocumentViewer.Document property to RichTextBox.Document

绑定:

<的DocumentViewer文档={约束力的文件,转换器= {StaticResource的FlowDocumentToPaginatorConverter}的ElementName = mainRTB,模式=单向}/>

这是转换器code:

 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            FlowDocument d = value as FlowDocument;
            DocumentPaginator pagin = ((IDocumentPaginatorSource)d).DocumentPaginator;
            FixedDocumentSequence result = null;
            Size s = new Size(793.700787402, 1122.519685039);
            pagin.PageSize = s;

            using (MemoryStream ms = new MemoryStream())
            {
                TextRange tr = new TextRange(d.ContentStart, d.ContentEnd);
                tr.Save(ms, DataFormats.XamlPackage);
                Package p = Package.Open(ms, FileMode.Create, FileAccess.ReadWrite);
                Uri uri = new Uri(@"memorystream://doc.xps");
                PackageStore.AddPackage(uri, p);
                XpsDocument xpsDoc = new XpsDocument(p);
                xpsDoc.Uri = uri;
                XpsDocument.CreateXpsDocumentWriter(xpsDoc).Write(pagin);
                result = xpsDoc.GetFixedDocumentSequence();
            }
            return result;
        }

当我启动这个应用程序一切正常,直到我切换到标签用的DocumentViewer。应用压碎,我得到这样的例外:

When I start this application everything is ok until I switch to tab with DocumentViewer. Application crushes and I get such Exception:

不能在只写模式执行读操作。

Cannot perform a read operation in write-only mode.

我做错了吗?是否有可能使这种结合?

What I am doing wrong? Is it possible to make this binding?

推荐答案

该错误消息的确是令人困惑和理由不立即明显。基本上你是关闭的MemoryStream 持有 XpsDocument 太早,当的DocumentViewer 尝试读取该文件它不能因为它是只写模式(因为在流关闭)。

The error message is indeed confusing and reason not immediately obvious. Basically you are closing the MemoryStream that holds XpsDocument too early and when the DocumentViewer attempts to read the document it cannot as it is write-only mode (because the stream was closed).

该解决方案是不立即关闭的MemoryStream 直到查看完文档。为了实现这一目标,我写了 XpsDocumentConverter 的回报 XpsReference

The solution is to not immediately close the MemoryStream until after you have finished viewing the document. To achieve this I wrote an XpsDocumentConverter that returns XpsReference.

此外,因为你从来没有能够转换并显示一个 XpsDocument 你不会还没有遇到过在<$ C $有多个包下一期C> PackageStore 用相同的乌里。我在下面执行照顾这一点。

Also, as you never been able to convert and display a single XpsDocument you won't have yet encountered the next issue of having multiple packages in the PackageStore with the same Uri. I have taken care of this in my implementation below.

public static XpsDocumentReference CreateXpsDocument(FlowDocument document)
{            
    // Do not close the memory stream as it still being used, it will be closed 
    // later when the XpsDocumentReference is Disposed.
    MemoryStream ms = new MemoryStream();

    // We store the package in the PackageStore
    Uri uri = new Uri(String.Format("pack://temp_{0}.xps/", Guid.NewGuid().ToString("N")));
    Package pkg = Package.Open(ms, FileMode.Create, FileAccess.ReadWrite);
    PackageStore.AddPackage(uri, pkg);
    XpsDocument xpsDocument = new XpsDocument(pkg, CompressionOption.Normal, uri.AbsoluteUri);

    // Need to force render the FlowDocument before pagination. 
    // HACK: This is done by *briefly* showing the document.
    DocumentHelper.ForceRenderFlowDocument(document);

    XpsSerializationManager rsm = new XpsSerializationManager(new XpsPackagingPolicy(xpsDocument), false);
    DocumentPaginator paginator = new FixedDocumentPaginator(document, A4PageDefinition.Default);            
    rsm.SaveAsXaml(paginator);

    return new XpsDocumentReference(ms, xpsDocument);
}

public class XpsDocumentReference : IDisposable
{
    private MemoryStream MemoryStream;            
    public XpsDocument XpsDocument { get; private set; }
    public FixedDocument FixedDocument { get; private set; }

    public XpsDocumentReference(MemoryStream ms, XpsDocument xpsDocument)
    {
        MemoryStream = ms;
        XpsDocument = xpsDocument;

         DocumentReference reference = xpsDocument.GetFixedDocumentSequence().References.FirstOrDefault();
         if (reference != null)
             FixedDocument = reference.GetDocument(false);
    }

    public void Dispose()
    {
        Package pkg = PackageStore.GetPackage(XpsDocument.Uri);
        if (pkg != null)
        {
            pkg.Close();
            PackageStore.RemovePackage(XpsDocument.Uri);
        }

        if (MemoryStream != null)
        {
            MemoryStream.Dispose();
            MemoryStream = null;
        }
    }

}

XpsReference 工具的IDisposable 所以记得要叫的Dispose()就可以了。

XpsReference implements IDisposable so remember to call Dispose() on it.

此外,一旦你解决上述错误的下一个问题,你很可能会遇到将是含量不呈现你所期望的。这是你需要复制的FlowDocument 造成的事实,也没有经过全面的措施,并安排布局传递。读
<一href=\"http://stackoverflow.com/questions/9447338/printing-blockuicontainer-to-xpsdocument-fixeddocument\">Printing BlockUIContainer到XpsDocument /固定文档就如何解决这个问题。

Also, once you resolve the above error the next problem you are likely to encounter will be content not rendering as you would expect. This is caused by the fact you need to clone FlowDocument and it has not undergone a full measure and arrange layout pass. Read Printing BlockUIContainer to XpsDocument/FixedDocument on how to solve this.

这篇关于要的DocumentViewer RichTextBox的绑定错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆