Reputation: 564
I have a very simple WPF application with only one button on it.
<Button x:Name="btnPrintCard" Grid.Row="2" HorizontalAlignment="Center" Content="Print Card" MinWidth="140" Foreground="White"
Cursor="Hand" Background="#008080" Click="btnPrintCard_Click" />
I am trying to print multiple cards with size 3.370 x 2.125 on Typical A4 page. if arranged properly it should fit 10 cards per sheet from order left to right. Exactly like, adobe reader print command and setting custom page per sheet to 2 x 5.
I am generating and printing card using below code:
private void btnPrintCard_Click(object sender, RoutedEventArgs e)
{
try
{
PrintDialog printDialog = new PrintDialog();
bool? pdResult = printDialog.ShowDialog();
if (pdResult != null && pdResult.Value)
{
FixedDocument document = CreateFixedDocument();
printDialog.PrintDocument(document.DocumentPaginator, "ID Card Printing");
}
MessageBox.Show("Printing done.");
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message + " :: " + ex.InnerException);
}
}
private FixedDocument CreateFixedDocument()
{
FixedDocument fixedDocument = new FixedDocument();
// fixedDocument.DocumentPaginator.PageSize = new Size(96 * 3.370, 96 *2.125);
fixedDocument.DocumentPaginator.PageSize = new Size(96 * 8.5, 96 * 11);
for (int i = 0; i < 10; i++)
{
PageContent page = new PageContent();
FixedPage fixedPage = CreateOneFixedPage();
((IAddChild)page).AddChild(fixedPage);
fixedDocument.Pages.Add(page);
}
return fixedDocument;
}
private FixedPage CreateOneFixedPage()
{
FixedPage page = new FixedPage();
page.Background = Brushes.Red;
page.Width = 96 * 3.370;
page.Height = 96 * 2.125;
TextBlock tbTitle = new TextBlock();
tbTitle.Text = "xxx xxxxx Public School";
tbTitle.FontSize = 24;
tbTitle.Foreground = new SolidColorBrush(Colors.White);
tbTitle.FontFamily = new FontFamily("Arial");
FixedPage.SetLeft(tbTitle, 96 * 0.4); // left margin
FixedPage.SetTop(tbTitle, 96 * 0.04); // top margin
page.Children.Add((UIElement)tbTitle);
Image image = new Image
{
Source = new BitmapImage(new Uri("http://www.ready-range.co.uk/_assets/images/products/BHSRR40R0R.jpg")),
Height = 30,
Width = 30
};
Border b = new Border();
b.BorderThickness = new Thickness(1);
b.BorderBrush = Brushes.Yellow;
b.Child = image;
FixedPage.SetLeft(b, 96 * 0.3);
FixedPage.SetTop(b, 96 * 0.6); // top margin
page.Children.Add((UIElement)b);
//measure size of the layout
Size sz = new Size(96 * 3.370, 96 * 2.125);
page.Measure(sz);
page.Arrange(new Rect(new Point(), sz));
page.UpdateLayout();
return page;
}
It result in printing successfully but with each card per page like this:
The problem is I want to print like above first image i.e. custom 2 by 5 per sheet.
Many Thanks.
Upvotes: 1
Views: 4306
Reputation: 564
This answer from another stackoverflow question helped a lot. I made some changes in order to get desire result which is adding my own method in the WpfPrint
Class.
/// <summary>
/// Add fixed page to current fixed document
/// </summary>
/// <param name="card"></param>
/// <param name="flags"></param>
public void AddFixedPage(FixedPage card, ElementFlags flags)
{
card.Measure(_infiniteSize);
if (CurX > _fixedDocument.DocumentPaginator.PageSize.Width - MarginX)
{
CurY += card.DesiredSize.Height + MarginY;
CurX = MarginX;
}
double extraCheck = 0;
if ((flags & ElementFlags.BottomCheck2) == ElementFlags.BottomCheck2)
extraCheck = card.DesiredSize.Height;
if (CurY > _fixedDocument.DocumentPaginator.PageSize.Height - MarginY - extraCheck)
StartPage();
_curCanvas.Children.Add(card);
card.SetValue(Canvas.LeftProperty, CurX);
card.SetValue(Canvas.TopProperty, CurY);
CurX += card.DesiredSize.Width + MarginX; //Added margin x for proper display
if (((flags & ElementFlags.NewLine) == ElementFlags.NewLine) || CurX + card.DesiredSize.Width > _fixedDocument.DocumentPaginator.PageSize.Width)
{
CurX = MarginX;
CurY += card.DesiredSize.Height + MarginY;
}
}
Now we can simply do this like this:
WpfPrint printer = new WpfPrint(new Size(96 * 9, 96 * 11));
printer.CurrentElementMargin = new Thickness(4);
printer.CurrentFontFamily = new FontFamily("Arial");
printer.MarginX = 20;
printer.MarginY = 10;
Now we can loop through every FixedPage:
for (int i = 0; i < 10; i++)
printer.AddFixedPage(CreateOneFixedPage(), WpfPrint.ElementFlags.BottomCheck2);
Finally, send print command like this:
PrintDialog printDialog = new PrintDialog();
bool? pdResult = printDialog.ShowDialog();
if (pdResult != null && pdResult.Value)
printDialog.PrintDocument(printer.CurrentFixedDocument.DocumentPaginator, "Card Printing");
Thanks.
Upvotes: 1