打印BlockUIContainer到XpsDocument/FixedDocument问题如何使用BlockUIContainer打印FlowDocument?如何在FlowDocument上执行测量/更新/安排?背景我有一个生成的FlowDocument,其中包含一些文本段落,一些Rectangle元素填充了来自资源字典的DrawingBrushes和一个带有自定义控件的BlockUIContainer。当文档转换为FixedDocument/XpsDocument时,当在任何FlowDocument*控件中查看时文档会正确呈现,而Rectangle和BlockUIContainer元素都不会呈现。我几乎可以肯定这是因为没有测量/排列控件,但在转换为XpsDocument之前无法弄清楚如何强制执行。打印XpsDocument代码Uriuri=newUri(String.Format("pack://temp_{0}.xps/",Guid.NewGuid().ToString("N")));MemoryStreamms=newMemoryStream();Packagepkg=Package.Open(ms,FileMode.Create,FileAccess.ReadWrite);PackageStore.AddPackage(uri,pkg);XpsDocumentxpsDocument=newXpsDocument(pkg,CompressionOption.Normal,uri.AbsoluteUri);XpsSerializationManagerrsm=newXpsSerializationManager(newXpsPackagingPolicy(xpsDocument),falsePacumentPacument);=newFixedDocumentPaginator(clonedDocument,A4PageDefinition.Default);rsm.SaveAsXaml(分页器);返回新的XpsDocumentReference(ms,xpsDocument);如您所见,我还使用了一个名为“FixedDocumentPaginator”的自定义DocumentPaginator;但我不会发布该代码,因为我怀疑问题出在在那里,因为当它开始在GetPage(intpageNumber)处对文档进行分页时,所有内容都已经转换为Visual,并且布局编辑已经太晚了嗯。当我输入这个时,我突然想到克隆文档可能没有完成Measure/Arrange/UpdateLayout。问题:如何对FlowDocument执行测量/更新/安排?我可以开始工作的一种可能的技巧是在FlowDocumentViewers(可能在屏幕外)中显示克隆的文档。我刚刚了解到的另一种可能的解决方案是调用:ContextLayoutManager.From(Dispatcher.CurrentDispatcher).UpdateLayout();ContextLayoutManager为您执行ContextLayoutManager逻辑树并更新布局。克隆文档的代码publicstaticFlowDocumentClone(FlowDocumentoriginalDocument){FlowDocumentclonedDocument=newFlowDocument();TextRangesourceDocument=newTextRange(originalDocument.ContentStart,originalDocument.ContentEnd);TextRangeclonedDocumentDocument.ContentRange=newTextRange,clontStart.clontDocument.clontStartRange(ContentEnd);尝试{使用(MemoryStreamms=newMemoryStream()){sourceDocument.Save(ms,DataFormats.XamlPackage);clonedDocumentRange.Load(ms,DataFormats.XamlPackage);}clonedDocument.ColumnWidth=originalDocument.ColumnWidth;clonedDocument.PageWidth=originalDocument.PageWidth;clonedDocument.PageHeight=originalDocument.PageHeight;clonedDocument.PagePadding=originalDocument.PagePadding;clonedDocument.LineStackingStrategy=clonedDocument.LineStackingStrategy;返回克隆文档;}赶上(异常){}返回空;将此作为与FlowDocument/FixedDocument/XpsDocument其他具有类似渲染问题的未来参考帖子。需要注意的几点:ForceRenderFlowDocumentprivatestaticstringForceRenderFlowDocumentXaml=@"";publicstaticvoidForceRenderFlowDocument(FlowDocumentdocument){使用(varreader=newXmlTextReader(newStringReader(ForceRenderFlowDocumentXaml))){Windowwindow=XamlReader).Load(asWindow;FlowDocumentScrollViewerviewer=LogicalTreeHelper.FindLogicalNode(window,"viewer")asFlowDocumentScrollViewer;viewer.Document=document;//离屏方式显示窗口window.WindowStartupLocation=WindowStartupLocation.Manual;window.Top=Int32.MaxValuewindow.Left=Int32.MaxValue;window.ShowInTaskbar=false;window.Show();//确保调度程序已完成布局和渲染过程Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Loaded,newAction(()=>{}));viewer.Document=null;window.Close();}}编辑:我刚刚在方法中添加了window.ShowInTaskbar=false,就像您很快就会看到窗口出现在任务栏中一样。用户永远不会“看到”窗口,因为它位于屏幕上的Int32.MaxValue-这是早期多媒体创作(例如Macromedia/AdobeDirector)中的常见技巧。对于搜索和发现此问题的任何人,我可以告诉您,没有其他方法可以强制呈现文档。视觉和视觉树助手publicstaticstringWriteVisualTree(DependencyObjectparent){if(parent==null)return"NoVisualTreeAvailable.DependencyObjectisnull.";使用(varstringWriter=newStringWriter())使用(varindentedTextWriter=newIndentedTextWriter(stringWriter,"")){WriteVisualTreeRecursive(indentedTextWriter,parent,0);返回stringWriter.ToString();}}privatestaticvoidWriteVisualTreeRecursive(IndentedTextWriterwriter,DependencyObjectparent,intindentLevel){if(parent==null)return;intchildCount=VisualTreeHelper.GetChildrenCount(parent);stringtypeName=parent.GetType().Name;stringobjName=parent.GetValue(FrameworkElement.NameProperty)作为字符串;writer.Indent=indentLevel;writer.WriteLine(String.Format([{0:000}]{1}({2}){3}",indentLevel,String.IsNullOrEmpty(objName)?typeName:objName,typeName,childCount));for(intchildIndex=0;childIndex();intchildCount=children.Count();stringtypeNa我=parent.GetType().Name;stringobjName=parent.GetValue(FrameworkElement.NameProperty)作为字符串;doubleactualWidth=(parent.GetValue(FrameworkElement.ActualWidthProperty)asdouble?).GetValueOrDefault();doubleactualHeight=(parent.GetValue(FrameworkElement.ActualHeightProperty)asdouble?).GetValueOrDefault();writer.Indent=indentLevel;writer.WriteLine(String.Format([{0:000}]{1}({2}){3}",indentLevel,String.IsNullOrEmpty(objName)?typeName:objName,typeName,childCount));foreach(LogicalTreeHelper.GetChildren(parent)中的对象子项){if(childisDependencyObject)WriteLogicalTreeRecursive(writer,(DependencyObject)child,indentLevel+1);}}用法#ifDEBUGDebug.WriteLine("---Start------");Debug.WriteLine(VisualAndLogicalTreeHelper.WriteLogicalTree(文档));Debug.WriteLine("---结束-------");#endif我在这里找到了这个解决方案,它帮助我在不将FlowDocment渲染到屏幕的情况下进行打印……所以我希望它对你有帮助!以上就是C#学习教程:PrintBlockUIContainertoXpsDocum如果ent/FixedDocument分享的所有内容对你有用,需要进一步了解C#学习教程,希望大家多多关注——StringcopyString=XamlWriter.Save(flowDocViewer.Document);FlowDocumentcopy=XamlReader.Parse(copyString)asFlowDocument;本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处:
