Print list of visuals in WPF
Visual is the Class in System.Windows.Media
PrinterSettings is the Class in System.Drawing
PrintServer, PrintQueue and EnumeratedPrintQueueTypes are the Classes in System.Printing
XpsDocumentWriter and VisualsToXpsDocument are the Classes in System.Windows.Xps
So, before applying this code, you need to add following assembly references:
-> System.Windows.Media
-> System.Windows.Xps
-> System.Windows.Drawing
-> System.Printing
* This code can also used to fit the visual to the page
* If you select the PDF Xchange for printing, all visuals will get saved into a single pdf file with each visual on each page.
* This code can also used to fit the visual to the page
* If you select the PDF Xchange for printing, all visuals will get saved into a single pdf file with each visual on each page.
//Create local variables
private int m_visualsCount;
private ObservableCollection<Visual> m_listVisuals = new ObservableCollection<Visual>();
//Define and initiate PrintDialog which is necessary for printing
//PrintDialog is in System.Windows.Controls
PrintDialog printDialog = new PrintDialog();
//Pass list of visuals through your constructor
public Constructor(ObservableCollection<Visual> listVisuals)
{
InitializeComponent();
m_visualsCount = listVisuals.Count; //Calculate number of visuals and assign to local variable
m_listVisuals = listVisuals; //Assign all visuals in the list to local variable
//Define and initiate PrinterSettings and get the default printer name
var printersettings = new PrinterSettings();
string st = printersettings.PrinterName;
//Now get all the installed printers on your system into a ComboBox (it can be any other element as well)
foreach (string str in PrinterSettings.InstalledPrinters)
{
combo.Items.Add(str);
}
//Default selection of printer in ComboBox
for (int i = 0; i < PrinterSettings.InstalledPrinters.Count; i++)
{
if (PrinterSettings.InstalledPrinters[i].Equals(st))
{
combo.SelectedIndex = i;
}
}
//Now initiate the PrintServer and get Print Queues
var server = new PrintServer();
var queues = server.GetPrintQueues(new[] { EnumeratedPrintQueueTypes.Local, EnumeratedPrintQueueTypes.Connections});
//Set the status of selected printer(just to display on GUI)
foreach (var queue in queues)
{
if(st.Equals(queue.FullName))
{
sp.Text(any textbox in Xaml code) = queue.QueueStatus.ToString();
}
}
//To show the number of pages to be printed
pagesCount.Text(any textbox in Xaml code) = m_visualsCount.ToString();
}
//When the printing is initiated
private void buttonDone_Click(object sender, RoutedEventArgs e)
{
//Get the printer, server and queue that are currently selected
string str = PrinterSettings.InstalledPrinters[combo.SelectedIndex];
var server = new PrintServer();
var queues = server.GetPrintQueues(new[] { EnumeratedPrintQueueTypes.Local, EnumeratedPrintQueueTypes.Connections });
Find the selected printer for printing
foreach (var queue in queues)
{
if (str.Equals(queue.FullName))
{
// Get an XpsDocumentWriter for the default print queue
XpsDocumentWriter xpsdw = PrintQueue.CreateXpsDocumentWriter(queue);
VisualsToXpsDocument vtxd = (VisualsToXpsDocument)xpsdw.CreateVisualsCollator();
//Begin the batchwrite
vtxd.BeginBatchWrite();
//Scale and Write all visuals
for (int count = 0; count < m_visualsCount; count++)
{
if (m_listVisuals[count] != null)
{
//Scale the visual
Visual scaledVisual = ScaleVisual(m_listVisuals[count], queue);
//get selected printer capabilities
PrintCapabilities capabilities = printDialog.PrintQueue.GetPrintCapabilities(printDialog.PrintTicket);
//get scale of the print wrt to screen of WPF visual
double scale = Math.Min(capabilities.PageImageableArea.ExtentWidth / this.ActualWidth,
capabilities.PageImageableArea.ExtentHeight / this.ActualHeight);
//Transform the Visual to scale
this.LayoutTransform = new ScaleTransform(scale, scale);
//get the size of the printer page
Size sz = new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);
//update the layout of the visual to the printer page size.
this.Measure(sz);
this.Arrange(new Rect(new Point(capabilities.PageImageableArea.OriginWidth, capabilities.PageImageableArea.OriginHeight), sz));
//Now write the visual to printer to fit on the one page.
vtxd.Write(scaledVisual);
}
}
//Mark the end of the batch operation.
vtxd.EndBatchWrite();
this.Close();
}
}
}
}
}
//Setting the properties of Selected Printer
private void combo_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string st = combo.SelectedValue.ToString();
var server = new PrintServer();
var queues = server.GetPrintQueues(new[] { EnumeratedPrintQueueTypes.Local, EnumeratedPrintQueueTypes.Connections });
foreach (var queue in queues)
{
if (st.Equals(queue.FullName))
{
sp.Text = queue.QueueStatus.ToString();
printDialog.PrintQueue = queue;
printDialog.PrintTicket = queue.UserPrintTicket;
}
}
}
}
}
//We should able to scale the visual so it fits within the page.
private Visual ScaleVisual(Visual visual, PrintQueue printQueue)
{
ContainerVisual root = new ContainerVisual();
//An inch is 96 DIPs, use this to scale up sizes given in inches.
double inch = 96;
//Calculate our margins.
double xMargin = 1.25 * inch;
double yMargin = 1 * inch;
//Get the current print ticket from which the paper size can be obtained.
PrintTicket printTicket = printQueue.UserPrintTicket;
//Retrieve the dimensions of the target page.
double pageWidth = printTicket.PageMediaSize.Width.Value;
double pageHeight = printTicket.PageMediaSize.Height.Value;
double xScale = (pageWidth - xMargin * 2) / pageWidth;
double yScale = (pageHeight - yMargin * 2) / pageHeight;
root.Children.Add(visual);
root.Transform = new MatrixTransform(xScale, 0, 0, yScale, xMargin, yMargin);
return root;
}
Thanks for sharing such a wonderful article, I hope you could inspire more people. Visit my site too.
ReplyDeleten8fan.net
www.n8fan.net
Once I originally commented I clicked the -Notify me when new comments are added- checkbox and now every time a comment is added I get four emails with the identical comment. Is there any means you'll be able to remove me from that service? Thanks! betfair online casino
ReplyDelete