Home » WPFRSS

Printing in WPF

I've been playiing around trying to print a grid in Landscape sized to fit the page and with equal size columns.

I created a user control with a datagrid and set the column widths to star.

EntrySheet.xaml:

<UserControl x:Class="OodHelper.net.EntrySheet"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      mc:Ignorable="d"
      d:DesignHeight="424" d:DesignWidth="1108">
    <UserControl.Resources>
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="Padding" Value="0,6"/>
            <Setter Property="FontWeight" Value="Bold"/>
        </Style>
        <Style TargetType="{x:Type DataGridColumnHeader}">
            <Setter Property="FontWeight" Value="Bold" />
            <Setter Property="Background" Value="#eeeeee" />
            <Setter Property="Padding" Value="4" />
            <Setter Property="Margin" Value="0" />
            <Setter Property="BorderThickness">
                <Setter.Value>
                    <Thickness Bottom="0" Left="1" Right="0" Top="1"/>
                </Setter.Value>
            </Setter>
            <Setter Property="BorderBrush" Value="Black"/>
        </Style>
        <Style TargetType="{x:Type DataGridCell}">
            <Setter Property="BorderThickness">
                <Setter.Value>
                    <Thickness Bottom="0" Left="1" Right="0" Top="1"/>
                </Setter.Value>
            </Setter>
            <Setter Property="BorderBrush" Value="Black"/>
        </Style>
    </UserControl.Resources>
    <Grid Margin="24,24">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal" Grid.ColumnSpan="3" HorizontalAlignment="Center">
            <TextBlock Text="Entry sheet for " />
            <TextBlock Name="EventName">Wed A Series</TextBlock>
            <TextBlock Name="EventDescription" Text=" - "/>
            <TextBlock Name="ClassName">Division 1</TextBlock>
        </StackPanel>
        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <TextBlock Text="Date: " />
            <TextBlock Name="StartDate">03 Aug 2010</TextBlock>
        </StackPanel>
        <StackPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal">
            <TextBlock Text="Start: " />
            <TextBlock Name="StartTime">13.00</TextBlock>
        </StackPanel>
        <StackPanel Grid.Row="1" Grid.Column="2" Orientation="Horizontal">
            <TextBlock Text="OOD: " />
            <TextBlock Name="OOD">Rothi</TextBlock>
        </StackPanel>
        <StackPanel Grid.Row="2" Orientation="Horizontal">
            <TextBlock Text="Course: " />
            <Line Margin="5" VerticalAlignment="Bottom" X1="0" Y1="0" X2="200" Y2="0"  Stroke="Black" StrokeThickness="1"/>
        </StackPanel>
        <StackPanel Grid.Row="2" Grid.Column="1" Orientation="Horizontal">
            <TextBlock Text="Actual Start: " />
            <Line Margin="5" VerticalAlignment="Bottom" X1="0" Y1="0" X2="80" Y2="0"  Stroke="Black" StrokeThickness="1"/>
        </StackPanel>
        <StackPanel Grid.Row="2" Grid.Column="2" Orientation="Horizontal">
            <TextBlock Text="Weather: " />
            <Line Margin="5" VerticalAlignment="Bottom" X1="0" Y1="0" X2="200" Y2="0"  Stroke="Black" StrokeThickness="1"/>
        </StackPanel>
        <DataGrid Grid.Row="3" Grid.ColumnSpan="3" Name="Entries"
                  CanUserReorderColumns="False" CanUserSortColumns="False"
                  BorderBrush="Black" GridLinesVisibility="None"
                  AutoGenerateColumns="False" IsReadOnly="True" RowHeight="40"
                  IsManipulationEnabled="False" HeadersVisibility="Column" >
            <DataGrid.BorderThickness>
                <Thickness Bottom="1" Left="0" Right="1" Top="0"/>
            </DataGrid.BorderThickness>
            <DataGrid.Columns>
                <DataGridTextColumn Header="Boat name" Width="*"/>
                <DataGridTextColumn Header="Class" Width="*"/>
                <DataGridTextColumn Header="Sail No" Width="*"/>
                <DataGridTextColumn Header="Lap 1" Width="*"/>
                <DataGridTextColumn Header="Lap 2" Width="*"/>
                <DataGridTextColumn Header="Lap 3" Width="*"/>
                <DataGridTextColumn Header="Lap 4" Width="*"/>
                <DataGridTextColumn Header="Lap 5" Width="*"/>
                <DataGridTextColumn Header="Lap 6" Width="*"/>
                <DataGridTextColumn Header="Lap 7" Width="*"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</UserControl>

And the code behind:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace OodHelper.net
{
    /// <summary>
    /// Interaction logic for EntrySheets.xaml
    /// </summary>
    public partial class EntrySheet : UserControl
    {
        public EntrySheet()
        {
            InitializeComponent();
            string[] row = new string[] { "", "", "", "", "", "", "", "", "", "" };
            for (int i = 0; i < 15; i++)
                Entries.Items.Add(row);
        }
    }
}

To print as simply as possible I tried the following:

                PrintDialog pd = new PrintDialog();
                pd.PrintTicket.PageOrientation = PageOrientation.Landscape;

                if (pd.ShowDialog() == true)
                {
                    EntrySheet es = new EntrySheet();
                    Size ps = new Size(pd.PrintableAreaWidth, pd.PrintableAreaHeight);
                    es.Measure(ps);
                    es.Arrange(new Rect(new Point(0, 0), ps));
                    es.UpdateLayout();
                    es.BeginInit();
                    es.EndInit();

                    XpsDocumentWriter xpwriter = PrintQueue.CreateXpsDocumentWriter(pd.PrintQueue);
                    xpwriter.Write(es, pd.PrintTicket);
                }

This prints in landscape but the columns dont size to fill the visible grid despite the grid filling the page width.

 

3 Answers Found

 

Answer 1

Hi David,

I tested it in the Visual Studio 2008 with WPF Toolkit DataGrid and in the Visual Studio 2010 with WPF 4 DataGrid. The WPF Toolkit DataGrid can measure and arrange the corrent value to fit  the width, and print  out correctly. It seems the DataGrid in WPF can not render the correct size, I tested and found the RenderSize of the DataGrid is about (1122, 793), but the RenderSize of one column  is about (20,25). It is wrong.

I will send it internal for investigation. Meanwhile, you can also submit a feedback on Microsoft Connect site regarding this issue. I'll update here if I get any feedbacks.

Thank you!

For your second example which uses the DocumentViewer to print, I think you do not change the Orientation for the printer, please try to change it and print.

Sincerely,

Bob Bao

MSDN Subscriber Support in Forum 

If you have any feedback on our support, please contact msdnmg@microsoft.com

 

Answer 2

Bob


Thanks for looking this.

Re Case 2, it's not reasonable having generated a Landscape orientated document to then have to select Landscape for the printer.  It should just happen. This is unworkable for a program used by other people because you have to tell people what they need to do at this stage.

The FixedDocument has the orientation albeit in the pagesize which isn't perfect.

In Word if you create a Landscape document and print  it, it will come out in Landscape, you don't need to select Landscape.

If it wont do it automatically then the DocumentViewer control  should let you set  something to indicate default orientation.  If the user  changes that that is there funeral!

I'll send in feedback on both.

Regards
David

 

Answer 3

Hi David,

Yse, in the Word, we can set the page  setup is for the PrintTicket. But in the FixedDocument.PageSize can not effect the PrintTicket. The PrintTicket value is independent with the FixedDocument.PageSize, we have to set  the value for the printer. For your case, you should set the FixDocument.PrintTicket and the PageSize property, that can allow the printer to print  the content in the specific direction.

Sincerely,

Bob Bao

 
 
Search for  Printing in WPF
 

<< Previous      Next >>


Microsoft   |   Windows   |   Visual Studio   |   Follow us on Twitter