首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DocumentViewer到RichTextBox绑定错误

DocumentViewer到RichTextBox绑定错误
EN

Stack Overflow用户
提问于 2012-03-10 14:56:53
回答 1查看 1.4K关注 0票数 2

我有一个RichTextBox和DocumentViewer (放在TabControl中)的应用程序,我想做一些类似于“热预览”的东西。我已经将DocumentViewer.Document属性绑定到RichTextBox.Document

具有约束力:

<DocumentViewer Document="{Binding Document, Converter={StaticResource FlowDocumentToPaginatorConverter}, ElementName=mainRTB, Mode=OneWay}" />

这是转换器代码:

代码语言:javascript
复制
 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切换到选项卡为止。应用程序崩溃了,我得到了这样的例外:

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

我做错什么了?有可能把这个绑起来吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-03-11 08:45:22

错误信息确实是令人困惑的,原因也不是很清楚。基本上,您正在过早关闭包含MemoryStreamXpsDocument,而当DocumentViewer试图读取文档时,由于它是只写模式(因为流已经关闭),它不能打开。

解决方案是,在MemoryStream完成查看之后,在之前不立即关闭。为了实现这一点,我编写了一个返回XpsDocumentConverterXpsReference

此外,由于您从未能够转换和显示单个XpsDocument,因此您还不会遇到在PackageStore中使用同一个Uri的多个包的下一个问题。我在下面的实施中已经处理了这一点。

代码语言:javascript
复制
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()

而且,一旦您解决了上述错误,您可能遇到的下一个问题将是内容不像您所期望的那样呈现。这是由于您需要克隆FlowDocument,并且它还没有经过一个完整的度量和布局传递。阅读Printing BlockUIContainer to XpsDocument/FixedDocument关于如何解决这一问题。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9647401

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档