Domandastampa BlockUIContainer a XpsDocument/FixedDocument
- Come si fa a stampare un FlowDocument che hanno
BlockUIContainer
? - Come posso forzare un Measure/Update/Arrange su un FlowDocument?
Sfondo
ho un generato FlowDocument
con paragrafi di testo con pochi Rectangle
elementi pieni DrawingBrushes
da un dizionario di risorse e BlockUIContainer
con controlli personalizzati.
Il documento rende correttamente quando visti in qualche FlowDocument * controlla Tuttavia quando il documento viene convertito in un FixedDocument/XpsDocument, nessuno dei Rectangle
o BlockUIContainer
elementi rendering.
Sono quasi certo che sia perché il controllo è non è stata misurata/arrangiate, tuttavia, non può capire come forza che accada prima di essere convertito nel XpsDocument.
ho percorso il
LogicalTree
in modo ricorsivo e fatto quanto segue,UIElement element = (UIElement)d; element.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); element.Arrange(new Rect(element.DesiredSize)); element.UpdateLayout();
dove
d
è unDependencyObject
. Riesco a vedere che questo imposta le proprietàActualWidth
eActualHeight
quando viene interrotto nel debugger.Ho provato costringendo il
Dispatcher
di rendere come suggerito da Will ♦.
codice utilizzato per stampare il 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);
}
}
Come potete vedere sto utilizzando anche un costume DocumentPaginator
chiamato 'FixedDocumentPaginator'; tuttavia, non inserirò il codice perché dubito che il problema sia presente al momento in cui inizia a impaginare il documento in GetPage(int pageNumber)
è già stato convertito un Visual
ed è troppo tardi per il layout.
Modifica
Hmm. Durante la digitazione, un pensiero mi è venuto in mente che il documento clonato potrebbe non aver avuto un Measure/Arrange/UpdateLayout
terminato.
Domanda: In che modo è possibile forzare una misura/aggiornamento/disposizione su un documento di flusso?
Una possibile modifica che potrei risolvere sarebbe quella di mostrare il documento clonato in uno dei FlowDocumentViewers (forse fuori dallo schermo).
Un'altra possibile soluzione che ho appena imparato a conoscere e non ho provato sarebbe quello di chiamare: ContextLayoutManager.From(Dispatcher.CurrentDispatcher).UpdateLayout();
ContextLayoutManager
passeggiate l'albero logico per voi e aggiorna il layout.
codice utilizzato per la clonazione del 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;
}
Grazie molto per questo, appena attraversato questo inferno me, hai aiutato un sacco =) – JMK
Cosa sta succedendo in 'XpsDocumentReference'? Continuo a provare a stampare da un 'PrintDialog' estraendo' DocumentPaginator' dal documento XPS tramite 'GetFixedDocumentSequence(). DocumentPaginator'. Ottengo un'eccezione Xaml di analisi risultante da un'eccezione InvalidURI. Apparentemente l'URI del documento fisso è stato alterato in qualche modo. –
@AustinMullins dai un'occhiata alla mia risposta all'indirizzo http://stackoverflow.com/questions/9647401/documentviewer-to-richtextbox-binding-error Mostra l'implementazione di 'XpsDocumentReference'. Sono passati alcuni anni da quando ho guardato XPS. Felice di rivisitare e aiutare.Sarebbe una buona opportunità per creare una libreria open source. – Dennis