要的DocumentViewer RichTextBox的绑定错误 [英] DocumentViewer to RichTextBox Binding Error
问题描述
我有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屋!