在 WPF 中以每张纸的页数打印具有多个 FixedPage 的 FixedDocument [英] Print FixedDocument with multiple FixedPage in pages per sheet in WPF

查看:139
本文介绍了在 WPF 中以每张纸的页数打印具有多个 FixedPage 的 FixedDocument的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常简单的 WPF 应用程序,上面只有一个按钮.

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" />

我正在尝试在典型的 A4 页面上打印多张尺寸为 3.370 x 2.125 的卡片.如果排列得当,它应该从左到右每张纸上放 10 张卡片.完全一样,adobe reader 打印命令并将每张纸的自定义页面设置为 2 x 5.

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:

问题是我想像上面的第一张图像一样打印,即每张自定义 2 x 5.

The problem is I want to print like above first image i.e. custom 2 by 5 per sheet.

非常感谢.

推荐答案

这个来自另一个 stackoverflow 问题的答案帮助很大.我进行了一些更改以获得所需的结果,即在 WpfPrint 类中添加我自己的方法.

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;

现在我们可以遍历每个 FixedPage:

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");

谢谢.

这篇关于在 WPF 中以每张纸的页数打印具有多个 FixedPage 的 FixedDocument的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆