Saltar al contenido

Imprimir cuadro de diálogo e imprimir cuadro de diálogo de vista previa para WPF

Solución:

Lo que quieres hacer es crear un xpsDocument del contenido que desea imprimir (un flowDocument) y usa eso XpsDocument para obtener una vista previa del contenido, por ejemplo, digamos que tiene lo siguiente Xaml, con un flowDocument que desea imprimir su contenido:

 <Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <FlowDocumentScrollViewer>
        <FlowDocument x:Name="FD">
            <Paragraph>
                <Image Source="http://www.wpf-tutorial.com/images/logo.png" Width="90" Height="90" Margin="0,0,30,0" />
                <Run FontSize="120">WPF</Run>
            </Paragraph>

            <Paragraph>
                WPF, which stands for
                <Bold>Windows Presentation Foundation</Bold> ,
                is Microsoft's latest approach to a GUI framework, used with the .NET framework.
                Some advantages include:
            </Paragraph>

            <List>
                <ListItem>
                    <Paragraph>
                        It's newer and thereby more in tune with current standards
                    </Paragraph>
                </ListItem>
                <ListItem>
                    <Paragraph>
                        Microsoft is using it for a lot of new applications, e.g. Visual Studio
                    </Paragraph>
                </ListItem>
                <ListItem>
                    <Paragraph>
                        It's more flexible, so you can do more things without having to write or buy new controls
                    </Paragraph>
                </ListItem>
            </List>

        </FlowDocument>
    </FlowDocumentScrollViewer>        
    <Button Content="Print" Grid.Row="1" Click="Button_Click"></Button>
</Grid>

el ejemplo de flowDocument es del sitio de tutoriales de Wpf

el botón de impresión Haga clic en el controlador de eventos debería tener este aspecto:

 private void Button_Click(object sender, RoutedEventArgs e)
    {
if (File.Exists("printPreview.xps"))
            {
                File.Delete("printPreview.xps");
            }
        var xpsDocument = new XpsDocument("printPreview.xps", FileAccess.ReadWrite);
        XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(xpsDocument);
        writer.Write(((IDocumentPaginatorSource)FD).DocumentPaginator);            
        Document = xpsDocument.GetFixedDocumentSequence();
        xpsDocument.Close();
        var windows = new PrintWindow(Document);
        windows.ShowDialog();
    }

public FixedDocumentSequence Document { get; set; }

así que aquí estás principalmente:

  • Crear un documento Xps y almacenarlo en un archivo printPreview.xps,
  • Escribiendo el FlowDocument contenido en ese archivo,
  • pasando el XpsDocument al PrintWindow en el que manejará la vista previa y las acciones de impresión,

aquí como el PrintWindow parece :

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="1.5*"/>
    </Grid.ColumnDefinitions>
    <StackPanel>
        <Button Content="Print" Click="Button_Click"></Button>
        <!--Other print operations-->
    </StackPanel>
    <DocumentViewer  Grid.Column="1" x:Name="PreviewD">            
    </DocumentViewer>
</Grid>

y el código detrás:

public partial class PrintWindow : Window
{
    private FixedDocumentSequence _document;
    public PrintWindow(FixedDocumentSequence document)
    {
        _document = document;
        InitializeComponent();
        PreviewD.Document =document;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        //print directly from the Xps file 
    }
}

el resultado final se parece a esto

ingrese la descripción de la imagen aquí

Ps: para usar XpsDocument, debe agregar una referencia al espacio de nombres System.Windows.Xps.Packaging

Sus requisitos se pueden lograr de varias formas, por ejemplo, puede utilizar el PrintDialog clase. Las siguientes páginas de MSDN contienen descripciones, así como algunos códigos de muestra:

  • WinForms: System.Windows.Forms.PrintDialog
  • WPF: System.Windows.Controls.PrintDialog (gracias a Bartosz)

Alternativamente, se puede lograr a través de C #, por ejemplo, considere el siguiente código:

 private string _previewWindowXaml =
    @"<Window
        xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation"
        xmlns:x ='http://schemas.microsoft.com/winfx/2006/xaml'
        Title="Print Preview - @@TITLE"
        Height="200" Width="300"
        WindowStartupLocation ='CenterOwner'>
                      <DocumentViewer Name="dv1"/>
     </Window>";

internal void DoPreview(string title)
{
    string fileName = System.IO.Path.GetRandomFileName();
    FlowDocumentScrollViewer visual = (FlowDocumentScrollViewer)(_parent.FindName("fdsv1"));

    try
    {
        // write the XPS document
        using (XpsDocument doc = new XpsDocument(fileName, FileAccess.ReadWrite))
        {
            XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
            writer.Write(visual);
        }

        // Read the XPS document into a dynamically generated
        // preview Window 
        using (XpsDocument doc = new XpsDocument(fileName, FileAccess.Read))
        {
            FixedDocumentSequence fds = doc.GetFixedDocumentSequence();

            string s = _previewWindowXaml;
            s = s.Replace("@@TITLE", title.Replace("'", "&apos;"));

            using (var reader = new System.Xml.XmlTextReader(new StringReader(s)))
            {
                Window preview = System.Windows.Markup.XamlReader.Load(reader) as Window;

                DocumentViewer dv1 = LogicalTreeHelper.FindLogicalNode(preview, "dv1") as DocumentViewer;
                dv1.Document = fds as IDocumentPaginatorSource;


                preview.ShowDialog();
            }
        }
    }
    finally
    {
        if (File.Exists(fileName))
        {
            try
            {
                File.Delete(fileName);
            }
            catch
            {
            }
        }
    }
} 

Qué hace: en realidad imprime el contenido de un objeto visual en un documento XPS. Luego carga el documento XPS “impreso” y lo muestra en un archivo XAML muy simple que se almacena como una cadena, en lugar de como un módulo separado, y se carga dinámicamente en tiempo de ejecución. La ventana resultante tiene los botones de DocumentViewer: imprimir, ajustar al ancho máximo de página, etc.

También agregué un código para ocultar el cuadro de búsqueda. Ver esta respuesta a WPF: ¿Cómo puedo eliminar el cuadro de búsqueda en un DocumentViewer? por cómo hice eso.

El efecto es así:

texto alternativo

El XpsDocument se puede encontrar en ReachFramework dll y el XpsDocumentWriter se puede encontrar en System.Printing dll, los cuales deben agregarse como referencias al proyecto.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *