Pages

Wednesday, June 27, 2012

In my last post I have explained how to print visual
elements using PrintVisual method of PrintDialog. In this post, I will explain how we can print flow
documents using Print Dialog class.

As I have explained earlier in my last post, PrintDialog class
provides PrintVisual and PrintDocument methods for printing. In this post I
will demonstrated how to use PrintDocument method to print Flow Document.

PrintDocument method
accepts document in form of DocumentPaginator with print description.
DocumentPaginator is a member of interface IDocumentPaginatorSource. To create document in WPF, majorly FlowDocument and FixedDocument classes are used. FlowDocument and FixedDocument both classes implements IDocumentPaginatorSource.
So while passing FlowDocument to PrintDocument method of PrintDialog class we
just need to pass DocumentPaginator of that document.

Let’s try to understand how to print FlowDocument using PrintDocument
method of PrintDialog.

XAML

<Window x:Class="WpfApplication1.PrintDocumentDemo"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="Print Document Demo" Height="300" Width="300">

<Grid>

<Grid.RowDefinitions>

<RowDefinition Height="0.9*" />

<RowDefinition Height="0.2*"/>

</Grid.RowDefinitions>

<FlowDocumentReader Grid.Row="0">

<FlowDocument Name="flowDocument">

<Paragraph FontSize="20"

FontWeight="Bold">Printing
document</Paragraph>

<Paragraph FontSize="15">This
is sample text to be printed.</Paragraph>

As demonstrated in above code, I have written XAML code to create FlowDocument under FlowDocumentReader and added few text lines
as paragraph which I wanted to print in page when user clicks on Print button.

In code, I have created an instance of PrintDialog class and set FlowDocument height and width to match with printable area of
PageDialog. After that I have called PrintDocument method of PrintDialog class and
passed DocumentPaginator of FlowDocument with some description.

Monday, June 25, 2012

Printing is quite simpler in WPF. In this post, I will
explain how to print elements using PrintDialog class of WPF.

WPF provides PrintDialog class which allows you to do
printing from WPF application. PrintDialog class is available in
System.Window.Controls namespace. PrintDialog provides various methods related
to print and print related settings. PrintDialog provides PrintVisual and
PrintDocument methods for printing. In this post I will demonstrated how to use
PrintVisual method.

In WPF, Framework Elements are directly or indirectly
derived from Visual class. You can read more about WPF class hierarchy here.
You can print any element which derives from Visual class using PrintVisual
method of PrintDialog class.

Let’s have a look on sample below.

XAML

<Window x:Class="WpfApplication1.PrintVisualDemo"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="Print Visual Demo" Height="350" Width="300">

<Grid>

<Grid.RowDefinitions>

<RowDefinition Height="0.9*" />

<RowDefinition Height="0.2*"/>

</Grid.RowDefinitions>

<StackPanel Name="printPanel"

Grid.Row="0"

Margin="5">

<Label Content="Sweet Baby"

HorizontalAlignment="Center"

FontSize="40"

FontFamily="Calibri">

<Label.Foreground>

<LinearGradientBrush Opacity="1" StartPoint="0,0.5" EndPoint="1,0.5">

<LinearGradientBrush.GradientStops>

<GradientStop Color="Blue" Offset="0" />

<GradientStop Color="Red" Offset="0.5" />

<GradientStop Color="Green" Offset="1" />

</LinearGradientBrush.GradientStops>

</LinearGradientBrush>

</Label.Foreground>

</Label>

<Image Source="D:\Temp\baby.jpg"

Height="150"

Width="200">

</Image>

</StackPanel>

<Button Content="Print"

Grid.Row="1" Margin="5"

Height="40" Width="150"

HorizontalAlignment="Center"

VerticalAlignment="Center" Click="Button_Click" />

</Grid>

</Window>

Code -

privatevoid Button_Click(object sender, RoutedEventArgs
e)

{

PrintDialog pd = newPrintDialog();

if (pd.ShowDialog() != true)
return;

pd.PrintVisual(printPanel, "Printing
StackPanel...");

}

Output –

As per the example, When you click on Print button it will
open print dialog. Select correct printer and hit print button, in my case I have
selected PDF Creator printer which will generate PDF file.

In code, I have just
created an instance of PrintDailog class and called its ShowDialog method. And last I
have called PrintVisual method from PrintDialog instance and passed Visual object
which I wanted to print with descriptions. In above example I have passed
StackPanel as Visual object which contains Text (Sweet Baby) and Image.

Instead of creating controls in XAML, you can dynamically
create those through code and similarly print using PrintVisual method. See below
code snippet.

privatevoid Button_Click(object sender, RoutedEventArgs
e)

{

StackPanel sp = newStackPanel();

TextBlock tb = newTextBlock();

tb.Text =
"Sweet Baby";

tb.FontSize = 40;

Image img = newImage();

img.Source =newBitmapImage(newUri(@"d:\temp\baby.jpg"));

img.Height = 150;

img.Width
= 200;

sp.Children.Add(tb);

sp.Children.Add(img);

PrintDialog pd = newPrintDialog();

if (pd.ShowDialog() != true)
return;

pd.PrintVisual(printPanel, "Printing
StackPanel...");

}

Let’s have a look on below sample which prints Canvas and elements inside.

XAML

<Window x:Class="WpfApplication1.PrintCanvasDemo"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="Print Canvas Demo" Height="400" Width="400">

<Grid>

<Grid.RowDefinitions>

<RowDefinition Height="0.9*" />

<RowDefinition Height="0.2*"/>

</Grid.RowDefinitions>

<Canvas Name="printCanvas"

Width="350" Height="280">

<TextBlock Text="This is sample text."

FontSize="18"

FontFamily="Arial"

Canvas.Top="20" Canvas.Left="60"/>

<Ellipse Height="100" Width="125"

Fill="LightBlue"

Stroke="Blue"

StrokeThickness="2"

Canvas.Right="35" Canvas.Bottom="55"/>

<Rectangle Height="15" Width="90"

Fill="Orange"

Stroke="Red"

Canvas.Top="80" Canvas.Left="150"
/>

<Polygon Points="140,160 80,185 50,127 130,20"

Stroke="Purple"

StrokeThickness="2"

Canvas.Top="90" Canvas.Left="0">

<Polygon.Fill>

<SolidColorBrush Color="Blue" Opacity="0.4"/>

</Polygon.Fill>

<Polygon.RenderTransform>

<RotateTransform CenterX="0" CenterY="250" Angle="-10" />

</Polygon.RenderTransform>

</Polygon>

</Canvas>

<Button Content="Print"

Grid.Row="1" Margin="5"

Height="40" Width="150"

HorizontalAlignment="Center"

VerticalAlignment="Center" Click="Button_Click" />

</Grid>

</Window>

privatevoid Button_Click(object sender, RoutedEventArgs
e)

{

PrintDialog pd = newPrintDialog();

if (pd.ShowDialog() != true)
return;

pd.PrintVisual(printCanvas, "Printing
Canvas...");

}

Above example demonstrates how we can print Canvas and its
elements. Canvas is also derived from Visual so we can print canvas using
PrintVisual method of PrintDialog class. In above example instead of StackPanel
I have passed Canvas as visual object.