Icono del sitio Programando a medianoche

Imprimir con Silverlight 4 beta

Una de las características más votadas en el sitio Microsoft® Connect por los desarrolladores que utilizamos Silverlight es la posibilidad de imprimir. Esto ahora es posible utilizando Silverlight 4 beta y la nueva clase PrintDocument del espacio de nombres System.Windows.Printing.

Primero vamos a hacer una introducción rápida sobre como imprimir desde Silverlight. La clase PrintDocument básicamente envía a la impresora el contenido de cualquier objeto UIElement, el cual debe ser establecido a través de uno de los parámetros del evento PrintPage que se dispara luego de llamar al método Print. Nótese que al tratarse de objetos UIElement se puede imprimir cualquier elemento gráfico que estemos utilizando en nuestras aplicaciones, por ejemplo, Image, TextBlock o incluso grillas complejas con elementos variados o con más grillas en su interior.

Supongamos que queremos imprimir, desde un botón puesto en el XAML, la pantalla de la aplicación (sería algo así como una captura de la aplicación), para esto podríamos poner el siguiente código en el XAML:

<UserControl x:Class="Print.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
        <TextBlock Text="Texto de prueba" Margin="10" FontSize="30">
            <TextBlock.Effect>
                <DropShadowEffect />
            </TextBlock.Effect>
        </TextBlock>
        <Button Content="Imprimir" Click="Button_Click" />
    </StackPanel>
</UserControl>

Y este otro en el código:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Printing;

namespace Print
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            PrintDocument objDoc = new PrintDocument();
            objDoc.PrintPage += (s, args) =>
            {
                args.PageVisual = this;
            };
            objDoc.Print();
         }
    }
}

En el código de C# podemos ver tres pasos sencillos realizados para imprimir la página Silverlight completa: creamos el objeto PrintDocument, creamos un delegado anónimo para el evento PrintDocument que establezca la propiedad PageVisual (aquí es donde hay que establecer el elemento a imprimir) y por último llamamos al método Print. Al llamar a este método el sistema operativo nos muestra el diálogo de impresión.

Para probar la impresión yo lo envié a la impresora virtual llamada “Microsoft XPS Document Writer”, para que me cree un archivo XPS y poder verlo luego desde mi navegador:

Bien, como ejemplo sirve, pero cómo hacemos para imprimir otra cosa que no sea la aplicación o para imprimir varias páginas? Eso lo voy a explicar a continuación.

La clase PrintDocument en realidad posee tres eventos: StartPrint, PrintDocument y EndPrint, los cuales se ejecutan antes, durante y después de realizar la impresión respectivamente.

El primer evento, StartPrint, se dispara luego de llamar al método Print y de que el usuario cliqueado “Imprimir” en el diálogo de impresión. Este evento es utilizado para configurar lo necesario antes de la impresión, por ejemplo, acomodar controles, ocultar elementos, etc.

El siguiente evento a ejecutar es PrintDocument, al cual se le pasa como parámetro un objeto del tipo PrintPageEventArgs. Este objeto posee tres propiedades interesantes:

Por último nos queda el evento EndPrint, donde podemos realizar cualquier acción que necesitemos hacer luego de finalizada (o enviada al spooler) la impresión. Este evento recibe, como uno de sus parámetros, un objeto del tipo EndPrintEventArgs, el cual tiene una propiedad llamada Error que es donde el Framework nos devuelve cualquier excepción generada al momento de la impresión. Si en el ejemplo anterior ante un error quisiéramos mostrarle al usuario el mensaje de la excepción, deberíamos modificar el código del evento Click del botón por el siguiente:

PrintDocument objDoc = new PrintDocument();
objDoc.PrintPage += (s, args) =>
{
    args.PageVisual = this;
};
objDoc.EndPrint += (s, args) =>
{
    if (args.Error != null)
        MessageBox.Show(args.Error.Message, "ERROR", MessageBoxButton.OK);
};
objDoc.Print();

Regresando a la clase PrintDocument, ésta posee también (además del método Print que ya vimos) una propiedad llamada DocumentName, donde podemos establecer el nombre de nuestro documento, el cual se verá en la cola de la impresora.

Por último les dejo el proyecto de ejemplo realizado con Visual Studio® 2010 beta 2.

Salir de la versión móvil