Este é um post disponível para assinantes MVPou para quem possui Créditos DevMedia. Clique aqui para saber mais!
Revista MSDN Magazine Edição 05 - Visualizar e imprimir no Windows Forms App com o namespace de impressão do .NET
Artigo Originalmente Publicado na MSDN Magazine Edição 05
Clique aqui para ler todos os artigos desta edição
Visualizar e imprimir no Windows Forms App com o namespace de impressão do .NET
por Alex Calvo
A impressão é parte integral de todo e qualquer aplicativo completo baseado em Windows. Fornecer recursos de impressão robustos nesses aplicativos sempre foi uma tarefa entediante. Agora, imprimir do Windows Forms com o .NET Framework significa que você deve adotar uma abordagem document-centric, o que resulta em um código mais limpo e gerenciável. Enquanto o namespace System.Windows.Forms fornece integração ininterrupta com todas as caixas de diálogo de impressão padrão (como Visualizar Impressão, Configurar Página e Imprimir), o namespace System.Drawing.Printing oferece inúmeras classes que permitem extensibilidade e customização. Essas classes, bem como a forma como oferecem acesso aos recursos de impressão, são discutidas neste artigo. Outras técnicas úteis também são explicadas, como a impressão em segundo plano, que permite ao usuário prosseguir com outras tarefas.
Do ponto de vista do desenvolvimento, o Microsoft® .NET mudou em praticamente tudo. Algumas dessas mudanças, como Web Forms e ADO.NET, exigiram grandes alterações na forma como as coisas são feitas, enquanto outras tiveram natureza mais evolucionária, simplesmente melhorando tecnologias existentes (como o System.Xml). Para o desenvolvedor tradicional, que usa Visual Basic® e Visual C++®, a impressão no Windows® Forms representa uma grande mudança. Porém, como no caso de grande parte do .NET Framework, essa mudança é definitivamente um avanço.
É o fim da era do objeto Print do Visual Basic e de sua coleção Printers. No .NET Framework, não há objeto Print monolítico e nunca mais será necessário configurar propriedades CurrentX e CurrentY nem emitir comandos como EndDoc e NewPage. Se você está conhecendo o .NET a partir do Visual C++, provavelmente sabe que imprimir pode ser uma tarefa entediante. Ela requer, por exemplo, que você acompanhe cuidadosamente o processo de impressão usando a API Win32® para assegurar que as páginas sejam impressas corretamente. A mudança não significa que você não precisará mais fazer isso. Contudo, com o .NET, você terá uma lógica de impressão mais limpa e de manutenção muito mais fácil. As classes do .NET Framework permitem que seu código de impressão seja completamente encapsulado. Como é possível derivar seu código a partir de um conjunto de classes básicas, você pode obter todos os tipos de recursos extras sem custo adicional. Vincular uma caixa de diálogo do tipo Visualizar Impressão é tarefa trivial no .NET, só para citar um exemplo.
A maioria dos exemplos de códigos deste artigo vem do exemplo do aplicativo de impressão disponível para download. Este exemplo de aplicativo Windows Forms, mostrado na Figura 1, demonstra muitos dos novos recursos aos quais você terá acesso ao imprimir no .NET. Ele permite que você escolha qualquer documento de texto e envie-o à caixa de diálogo Visualizar Impressão ou a uma impressora específica. Para fins de demonstração, forneço a opção para selecionar a exibição de uma marca d’água em cada página (opção Display watermark na Figura 1).

Figura 1 Aplicativo Windows Forms
Quando imprimir usando a caixa de diálogo Visualizar Impressão, você pode ativar ou desativar o recurso interno de anti-aliasing, que processa texto e elementos gráficos na tela com uma aparência mais suave. Lembre-se, no entanto, de que isso afeta a velocidade da saída de impressão. Além disso, a caixa de diálogo Visualizar Impressão aproveita automaticamente qualquer suavização de fonte fornecida pelo Windows (ClearType), reduzindo, assim, a necessidade de usar o anti-aliasing. Ao enviar a saída para a impressora, o exemplo do aplicativo de impressão (disponível para download) também permite que você selecione várias outras opções. Assim, você poderá decidir se deseja ou não exibir uma caixa de diálogo de status, mostrar uma impressora animada na barra de status ou imprimir em uma thread em segundo plano.
Vamos fazer um tour pela impressão do Windows Forms examinando primeiro a maneira rápida e “suja” de enviar saída para a impressora. Depois, analisarei em detalhes a forma correta de imprimir no Windows Forms — usando uma classe derivada PrintDocument.
Usando a classe PrintDocument
No Windows Forms, o processo de impressão é document-centric e orientado por eventos. A maior parte do esforço será aplicada no uso de um objeto PrintDocument genérico ou na implementação de uma classe derivada PrintDocument. A melhor opção é herdar da classe PrintDocument básica — pelos motivos que explicarei em breve. Entretanto, às vezes pode ser mais rápido e simples usar uma instância da classe básica PrintDocument.
Imprimir com uma classe PrintDocument básica exige que você envie o evento PrintPage da classe para um método de manipulação (estático ou de instância) cuja assinatura corresponda ao delegate PrintPageEventHandler. Esse evento será disparado quando seu código chamar o método Print em uma instância de um objeto PrintDocument. Para desenhar sua página, use a propriedade Graphics do objeto PrintPageEventArgs. Uma instância de uma classe PrintPageEventArgs é passada como argumento ao manipulador de evento PrintPage. A propriedade Graphics do objeto PrintPageEventArgs expõe um objeto GDI+ que encapsula a superfície sobre a qual você desenhou a página. (Voltarei a falar sobre os comandos GDI+ básicos mais adiante.) Para imprimir mais de uma página, notifique o controlador de impressão subjacente de que há mais coisas para imprimir. Faça isso usando a propriedade HasMorePages do objeto PrintPageEventArgs. Definir a propriedade HasMorePages como true garantirá que o manipulador de evento PrintPage seja chamado novamente.
Além disso, você pode configurar manipuladores de evento para outros eventos de impressão comuns, como BeginPrint, EndPrint e QueryPageSettings. BeginPrint é um bom ponto de partida para inicializar os objetos (como Fonts) dos quais a rotina PrintPage depende. O evento QueryPageSettings é imediatamente disparado antes de cada evento PrintPage. Ele permite que você imprima cada página usando diferentes configurações, o que pode ser feito modificando a propriedade QueryPageSettingsEventArgs.PageSettings. Para modificar as configurações de página para o documento inteiro, você pode usar a propriedade DefaultPageSettings da classe PrintDocument.
Veja um exemplo que ilustra como iniciar um trabalho de impressão usando a classe PrintDocument básica:
Este é um post disponível para assinantes MVPou para quem possui Créditos DevMedia. Clique aqui para saber mais!
Alex Calvo
Alex Calvo (acalvo@hotmail.com)é MCSD e MCAD for Microsoft .NET. Ele é co-fundador do Developer Box LLC (http://www.developerbox.com), empresa de consultoria especializada em .NET, Visual Basic, COM, e SQL Server.



