Preguntaimpresión BlockUIContainer a XpsDocument/FixedDocument
- ¿Cómo se imprime un FlowDocument que tienen
BlockUIContainer
? - ¿Cómo puedo forzar una Medida/Actualización/coloque en un FlowDocument?
Antecedentes
He generado un FlowDocument
con párrafos de texto con algunos elementos Rectangle
llenos DrawingBrushes
de un diccionario de recursos y BlockUIContainer
con controles personalizados.
El documento hace correctamente cuando se ve en cualquiera de los FlowDocument * Control Sin embargo cuando el documento se convierte a un FixedDocument/XpsDocument, ninguno de los Rectangle
o BlockUIContainer
elementos render.
Estoy casi seguro de que es porque el control no ha sido medido/arreglado, sin embargo no puedo encontrar la manera de forzarlo antes de convertirlo al XpsDocument.
ando la
LogicalTree
de forma recursiva y hecho lo siguiente,UIElement element = (UIElement)d; element.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); element.Arrange(new Rect(element.DesiredSize)); element.UpdateLayout();
donde
d
es unaDependencyObject
. Puedo ver que esto establece losActualWidth
yActualHeight
propiedades cuando señaló ruptura en el depurador.He intentado forzar el
Dispatcher
para representarlo como lo sugiere Will ♦.
código utilizado para imprimir el XpsDocument
public class XpsDocumentConverter
{
public static XpsDocumentReference CreateXpsDocument(FlowDocument document)
{
// Need to clone the document so that the paginator can work
FlowDocument clonedDocument = DocumentHelper.Clone<FlowDocument>(document);
Uri uri = new Uri(String.Format("pack://temp_{0}.xps/", Guid.NewGuid().ToString("N")));
MemoryStream ms = new MemoryStream();
Package pkg = Package.Open(ms, FileMode.Create, FileAccess.ReadWrite);
PackageStore.AddPackage(uri, pkg);
XpsDocument xpsDocument = new XpsDocument(pkg, CompressionOption.Normal, uri.AbsoluteUri);
XpsSerializationManager rsm = new XpsSerializationManager(new XpsPackagingPolicy(xpsDocument), false);
DocumentPaginator paginator = new FixedDocumentPaginator(clonedDocument, A4PageDefinition.Default);
rsm.SaveAsXaml(paginator);
return new XpsDocumentReference(ms, xpsDocument);
}
}
Como se puede ver también estoy usando una costumbre DocumentPaginator
llamado 'FixedDocumentPaginator'; Sin embargo no voy a publicar ese código como dudo que el problema está allí como en el momento en que comience a paginar el documento en GetPage(int pageNumber)
todo lo que ya se ha convertido un Visual
y es demasiado tarde para la disposición.
Editar
Hmm. Como he escrito esto, un pensamiento me acaba de ocurrir que el documento clonado no puede haber tenido un Measure/Arrange/UpdateLayout
hecho.
Pregunta: ¿Cómo puedo forzar una Measure/Update/Arrange en un FlowDocument?
Una posible truco que podía trabajar sería mostrar el documento clonado en uno de los FlowDocumentViewers (tal vez fuera de la pantalla).
Otra posible solución que acabo de aprender acerca y no lo he probado sería llamar: ContextLayoutManager.From(Dispatcher.CurrentDispatcher).UpdateLayout();
ContextLayoutManager
paseos del árbol lógico para usted y actualiza los datos de diseño.
Código utilizado para clonar el documento
public static FlowDocument Clone(FlowDocument originalDocument)
{
FlowDocument clonedDocument = new FlowDocument();
TextRange sourceDocument = new TextRange(originalDocument.ContentStart, originalDocument.ContentEnd);
TextRange clonedDocumentRange = new TextRange(clonedDocument.ContentStart, clonedDocument.ContentEnd);
try
{
using (MemoryStream ms = new MemoryStream())
{
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;
return clonedDocument;
}
catch (Exception)
{
}
return null;
}
Muchas gracias por esto, simplemente pasado por este infierno a mí mismo, que ayudó mucho =) – JMK
¿Qué está pasando en 'XpsDocumentReference'? Sigo tratando de imprimir desde un 'PrintDialog' tirando del' DocumentPaginator' del documento XPS a través de 'GetFixedDocumentSequence(). DocumentPaginator'. Obtengo una excepción de análisis Xaml resultante de una excepción InvalidURI. Aparentemente, el URI del documento fijo está mutilado de alguna manera. –
@AustinMullins eche un vistazo a mi respuesta en http://stackoverflow.com/questions/9647401/documentviewer-to-richtextbox-binding-error Muestra la implementación de 'XpsDocumentReference'. Han pasado algunos años desde que miré XPS. Feliz de visitar y ayudar.Sería una buena oportunidad para crear una biblioteca de código abierto. – Dennis