2018-02-16

Print WPF controls

This post will explain how to print WPF controls.

Create Custom Print button

Start with creating a UserControl with only print button on it.

<UserControl x:Class="PrintButton.PrintControl"
             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="20" d:DesignWidth="50">
    <Grid>
        <Button x:Name="Print"  
                Content="Print"                 
                Height="20"
                Width="50"                 
                Click="Print_Click" VerticalAlignment="Top" />
    </Grid>
</UserControl>



With code behind

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
 
namespace PrintButton
{
    /// <summary>
    /// Interaction logic for PrintButton.xaml
    /// </summary>
    public partial class PrintControl : UserControl
    {
        public PrintControl()
        {
            InitializeComponent();
        }
 
        public Visual ControlToPrint { getset; }
 
        private void Print_Click(object sender, RoutedEventArgs e)
        {
            var printDialog = new PrintDialog();
            if (printDialog.ShowDialog() != true)
                return;
 
            Print.Visibility = Visibility.Hidden;
            printDialog.PrintVisual(ControlToPrint, "Print");
            Print.Visibility = Visibility.Visible;
        }
    }
}

I hide button when we print something. In that way button will not be part of print document.

Use PrintControl

Next step is to use this UserControl in place where you want to print.

<Window x:Class="PrintButton.MainWindow"
        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"
        xmlns:local="clr-namespace:PrintButton"
        mc:Ignorable="d"
        Title="Print button demo" Height="200" Width="300">
    <Grid>
        <Grid.ColumnDefinitions >
            <ColumnDefinition Width="Auto" MinWidth="214" />
            <ColumnDefinition Width="Auto" MinWidth="15" />
        </Grid.ColumnDefinitions>
        
        <Grid x:Name="GridForPrint" Grid.Column="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <Label Grid.Row="0" Content="Header" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="14" FontWeight="Bold"/>
            <TextBlock Grid.Row="1"><Run Text="More text to print"/></TextBlock>
        </Grid>
 
 
        <local:PrintControl x:Name="Print"  
                            Grid.Column="1" 
                            HorizontalAlignment="Right" 
                            Margin="0,10,1,10" 
                            Width="50"  
                            ControlToPrint="{x:Reference Name=GridForPrint}" />
 
 
    </Grid>
</Window>
 
 
 

All we need to do is to give a name to the component that we want to print.
Then call our PrintControl referencing that component.

   <local:PrintControl  
          ControlToPrint="{x:Reference Name=GridForPrint}" />

Now each time print is clicked, Grid "GridForPrint" will be printed.