Pregunta

Tengo un FlowDocument que varía en altura debido a un ItemsControl en un BlockUIContainer. En algunos casos, el ItemsControl se extiende más allá de la altura de la página. ¿Hay una manera de escalar la FlowDocument para adaptarse a una página (8,5" x 11" ) justo antes de imprimir si es necesario?

A partir de ahora, la FlowDocument se llama 'doc' y el método para la impresión de que estoy usando es:

private void Print_Click(object sender, RoutedEventArgs e)
    {

        PrintDialog pd = new PrintDialog();
        doc.PageHeight = pd.PrintableAreaHeight;
        doc.PageWidth = pd.PrintableAreaWidth;
        doc.ColumnGap = 0;
        doc.ColumnWidth = pd.PrintableAreaWidth;
        IDocumentPaginatorSource dps = doc;
        pd.PrintDocument(dps.DocumentPaginator, "Sheet");
    }
¿Fue útil?

Solución

Sé que es un poco tarde, pero aquí es la solución que se me ocurrió.

En primer lugar, creamos un envoltorio que va a generar las páginas del documento para nosotros. Cada página tendrá una transformación de escala aplicado a ella antes de devolverlo.

public class FittedDocumentPaginator : DocumentPaginator
{
    public DocumentPaginator Base { get; private set; }
    public double Scale { get; private set; }
    private readonly ScaleTransform _sTransform;

    public FittedDocumentPaginator( DocumentPaginator baseDp, double scale )
    {
        if ( baseDp == null )
            throw new ArgumentNullException( "baseDp" );

        Base = baseDp;
        Scale = scale;
        _sTransform = new ScaleTransform( scale, scale );
    }

    public override DocumentPage GetPage( int pageNumber )
    {
        var page = Base.GetPage( pageNumber );
        ( (ContainerVisual)page.Visual ).Transform = _sTransform;

        return page;
    }

    public override bool IsPageCountValid
    {
        get { return Base.IsPageCountValid; }
    }

    public override int PageCount
    {
        get { return Base.PageCount; }
    }

    public override Size PageSize
    {
        get { return Base.PageSize; }
        set { Base.PageSize = value; }
    }

    public override IDocumentPaginatorSource Source
    {
        get { return Base.Source; }
    }
}

Su uso es bastante simple:

    private void PrintDocument( PrintDialog pd, FlowDocument document, double scale, string title )
    {
        DocumentPaginator dp = ( (IDocumentPaginatorSource)document ).DocumentPaginator;
        FittedDocumentPaginator fdp = new FittedDocumentPaginator( dp, scale );

        pd.PrintDocument( fdp, title );
    }

Si está interesado, aquí es cómo se determinó la escala. En nuestro caso, el documento se amplió más allá del ancho de la página, pero puede ser fácilmente modificado para dar cabida a la altura de la página.

    private void Print( FlowDocument document, string title, double documentWidth )
    {
        var pd = new PrintDialog();

        if ( pd.ShowDialog() == true )
        {
            // Set the printing margins.
            Thickness pageMargins = document.PagePadding;
            document.PagePadding = new Thickness( 15.0 );

            // In our case, the document's width is NaN so we have to navigate the visual tree to get the ActualWidth, which is represented by 'documentWidth'.
            double scale = documentWidth / pd.PrintableAreaWidth;

            if ( scale < 1.0 )
            {
                // The report fits on the page just fine. Don't scale.
                scale = 1.0;
            }

            double invScale = 1 / scale;

            document.PageHeight = pd.PrintableAreaHeight * scale;
            document.PageWidth = pd.PrintableAreaWidth * scale;

            DocumentPaginator dp = ( (IDocumentPaginatorSource)document ).DocumentPaginator;
            FittedDocumentPaginator fdp = new FittedDocumentPaginator( dp, invScale );

            pd.PrintDocument( fdp, title );

            // Restore the original values so the GUI isn't altered.
            document.PageHeight = Double.NaN;
            document.PageWidth = Double.NaN;
            document.PagePadding = pageMargins;
        }
    }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top