首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与FixedPage实例相同的WPF UserControl

与FixedPage实例相同的WPF UserControl
EN

Stack Overflow用户
提问于 2017-01-24 15:42:28
回答 1查看 986关注 0票数 0

首先,我不确定我是否正确地表述了标题。有一些UserControls是通过ViewModel添加的,我通过搜索VisualTree并将它们添加到ObservableCollection<Grid>中找到它们。我想要做的是将我从VisualTree中检索的每个VisualTree实例打印到一个FixedDocument中,但是每个UserControl都在一个页面上,直到它填充该页面并移到下一个页面。

下面是我当前的“打印按钮单击”事件的代码:

代码语言:javascript
复制
private async void btnPrint_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            if (tabMain.Items.Count > 0)
            {
                tab = new TabLayout();

                tab.Payslip = new ObservableCollection<Grid>();


                foreach (var grid in FindVisualChildren<Grid>(this))
                {
                    if (grid.Name == "pdfFile")
                    {
                        tab.Payslip.Add(grid);
                    }
                }

                FrameworkElement toPrint = new FrameworkElement();
                PrintDialog printDialog = new PrintDialog();

                PrintCapabilities capabilities = printDialog.PrintQueue.GetPrintCapabilities(printDialog.PrintTicket);
                Size pageSize = new Size(printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight);
                Size visibleSize = new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);
                FixedDocument fixedDoc = new FixedDocument();


                StackPanel panel = new StackPanel(); //was trying to stack them in a stackpanel first but it threw an exception about same instance of usercontrol blah blah...


                foreach (var doc in tab.Payslip.ToList())
                {

                    double yOffset = 0;

                    doc.Measure((new Size(double.PositiveInfinity, double.PositiveInfinity)));
                    doc.Arrange(new Rect(new Point(0, 0), doc.DesiredSize));

                    Size size = doc.DesiredSize;


                    while (yOffset < size.Height)
                    {
                        VisualBrush vb = new VisualBrush(doc);
                        vb.Stretch = Stretch.None;
                        vb.AlignmentX = AlignmentX.Left;
                        vb.AlignmentY = AlignmentY.Top;
                        vb.ViewboxUnits = BrushMappingMode.Absolute;
                        vb.TileMode = TileMode.None;
                        vb.Viewbox = new Rect(0, yOffset, visibleSize.Width, visibleSize.Height);

                        FixedPage page = new FixedPage();
                        PageContent pageContent = new PageContent();
                        ((IAddChild)pageContent).AddChild(page);
                        fixedDoc.Pages.Add(pageContent);
                        page.Width = fixedDoc.DocumentPaginator.PageSize.Width;
                        page.Height = fixedDoc.DocumentPaginator.PageSize.Height;

                        Canvas canvas = new Canvas();
                        FixedPage.SetLeft(canvas, capabilities.PageImageableArea.OriginWidth);
                        FixedPage.SetTop(canvas, capabilities.PageImageableArea.OriginHeight);
                        canvas.Width = visibleSize.Width;
                        canvas.Height = visibleSize.Height;
                        canvas.Background = vb;
                        page.Children.Add(canvas);
                        yOffset += visibleSize.Height;
                    }
                }
                //printDialog.PrintDocument(fixedDoc.DocumentPaginator, "");
                ShowPrintPreview(fixedDoc);
            }
        }
        catch(Exception ex)
        {
            var exceptionDialog = new MessageDialog
            {
                Message = { Text = ex.ToString() }
            };

            await DialogHost.Show(exceptionDialog, "RootDialog");
        }
    }

--这就是当我尝试打印三个Tabs (UserControls托管在Tabs中)时的样子: 就像你在这里看到的,它打印了三页

--我想把所有三个都放在一页上,如果我打印10个选项卡,那么它应该填充第一页,然后继续到下一页。

上一次我问类似的问题时,有人问我是否编写了代码。这段代码的零碎部分来自于FixedDocumentStackOverflow上的类似问题,但是它已经被编辑到了它对我实际起作用的程度。所以,是的,我知道FixedPage引用在foreach中是导致创建三个单独页面的原因,我理解代码。

摘要:

我想知道的是如何从每个UserControls中获取Tab,直到它满为止,而不需要获得“指定的元素已经是另一个元素的逻辑子元素。首先断开它”。错误。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-10 21:26:11

最后,我使用ItemsControlObservableCollection of Controls作为一个列表保存,并使用这个XpsDocumentWriter方法从ItemsControl中打印出来。

代码语言:javascript
复制
public void PrintItemsTo(ItemsControl ic, String jobName)
    {
        PrintDialog dlg = new PrintDialog();
        dlg.UserPageRangeEnabled = true;
        if (dlg.ShowDialog().GetValueOrDefault())
        {
            PageRange range = dlg.PageRange;
            //    range check - user selection starts from 1
            if (range.PageTo > ic.Items.Count)
                range.PageTo = ic.Items.Count;

            dlg.PrintQueue.CurrentJobSettings.Description = jobName;

            XpsDocumentWriter xdw = PrintQueue.CreateXpsDocumentWriter(dlg.PrintQueue);
            if (dlg.UserPageRangeEnabled == false || range.PageTo < range.PageFrom)
                WriteAllItems(ic, xdw);
            else
                WriteSelectedItems(ic, xdw, range);
        }
    }

    private void WriteAllItems(ItemsControl ic, XpsDocumentWriter xdw)
    {
        PageRange range = new PageRange(1, ic.Items.Count);
        WriteSelectedItems(ic, xdw, range);
    }

    private void WriteSelectedItems(ItemsControl ic, XpsDocumentWriter xdw, PageRange range)
    {
        IItemContainerGenerator generator = ic.ItemContainerGenerator;

        // write visuals using a batch operation
        VisualsToXpsDocument collator = (VisualsToXpsDocument)xdw.CreateVisualsCollator();

        collator.BeginBatchWrite();
        if (WritePageRange(collator, generator, range))
            collator.EndBatchWrite();
    }

    private bool WritePageRange(VisualsToXpsDocument collator, IItemContainerGenerator generator, PageRange range)
    {
        //    Get the generator position of the first data item
        //    PageRange reflects user's selection starts from 1
        GeneratorPosition startPos = generator.GeneratorPositionFromIndex(range.PageFrom - 1);
        //    If PageFrom > PageTo, print in reverse order
        //    UPDATE: never occurs; PrintDialog always 'normalises' the PageRange
        GeneratorDirection direction = (range.PageFrom <= range.PageTo) ? GeneratorDirection.Forward : GeneratorDirection.Backward;

        using (generator.StartAt(startPos, direction, true))
        {
            for (int numPages = Math.Abs(range.PageTo - range.PageFrom) + 1; numPages > 0; --numPages)
            {
                bool newlyRealized;

                // Get or create the child
                UIElement next = generator.GenerateNext(out newlyRealized) as UIElement;
                if (newlyRealized)
                {
                    generator.PrepareItemContainer(next);
                }

                //    The collator doesn't like ContentPresenters and produces blank pages
                //    for pages 2-n.  Finding the child of the ContentPresenter and writing
                //    that solves seems to solve the problem
                if (next is ContentPresenter)
                {
                    ContentPresenter presenter = (ContentPresenter)next;
                    presenter.UpdateLayout();
                    presenter.ApplyTemplate();    //    not sure if this is necessary
                    DependencyObject child = VisualTreeHelper.GetChild(presenter, 0);
                    if (child is UIElement)
                        next = (UIElement)child;
                }

                try
                {
                    collator.Write(next);
                }
                catch
                {
                    //    if user prints to Microsoft XPS Document Writer
                    //    and cancels the SaveAs dialog, we get an exception.
                    return false;
                }
            }
        }

        return true;
    }

PrintItemsTo()显示要打印到任何打印机的PrintDialog,而WriteAllItems则显示对话框以保存为PDF。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41832296

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档