3

How can I print the contents of a DataGrid. I have checked out the following post How can I produce a "print preview" of a FlowDocument in a WPF application? and it generates only the visible portion of the grid not the scrollable parts. I would need the preview to have multiple pages and I thiink I should be using the FlowDocument but I am not sure how to go about it. Any ideas would be appreciated.

Community
  • 1
  • 1
tribal
  • 219
  • 3
  • 14

2 Answers2

4

I had this issue some time ago. I wrote a method that generates a System.Windows.Documents.Table from the DataGrid. I put it in a FlowDocument and generated a fixed document thanks to an XpsDocumentWriter. You will then have a full paginated view of your DataGrid that you can visualize in a DocumentViewer

Sisyphe
  • 4,626
  • 1
  • 25
  • 39
  • Seems a good idea,I will try this out. Currently looking at [link](http://www.c-sharpcorner.com/uploadfile/manish1231/create-table-in-flow-document-in-wpf/) for help with creating the table – tribal Oct 24 '12 at 04:36
2

Use this: it works fine.

public class UIPrinter
{
    #region Properties

    public Int32 VerticalOffset { get; set; }
    public Int32 HorizontalOffset { get; set; }
    public String Title { get; set; }
    public UIElement Content { get; set; }

    #endregion

    #region Initialization

    public TimelinePrinter()
    {
        HorizontalOffset = 20;
        VerticalOffset = 20;
        Title = "Print " + DateTime.Now.ToMyStringWithTime();
    }

    #endregion

    #region Methods

    public Int32 Print()
    {
        var dlg = new PrintDialog();
        if (dlg.ShowDialog() == true)
        {
            //---FIRST PAGE---//
            // Size the Grid.
            Content.Measure(new Size(Double.PositiveInfinity,
                                     Double.PositiveInfinity));

            Size sizeGrid = Content.DesiredSize;

            //check the width
            if (sizeGrid.Width > dlg.PrintableAreaWidth)
            {
                MessageBoxResult result = MessageBox.Show(Properties.Resources.s_EN_Question_PrintWidth, "Print", MessageBoxButton.YesNo, MessageBoxImage.Question);
                if (result == MessageBoxResult.No)
                    throw new PrintAborted(Properties.Resources.s_EN_Info_PrintingAborted);
            }

            // Position of the grid 
            var ptGrid = new Point(HorizontalOffset, VerticalOffset);

            // Layout of the grid
            Content.Arrange(new Rect(ptGrid, sizeGrid));

            //print
            dlg.PrintVisual(Content, Title);

            //---MULTIPLE PAGES---//
            double diff;
            int i = 1;
            while ((diff = sizeGrid.Height - (dlg.PrintableAreaHeight - VerticalOffset*i)*i) > 0)
            {
                //Position of the grid 
                var ptSecondGrid = new Point(HorizontalOffset, -sizeGrid.Height + diff + VerticalOffset);

                // Layout of the grid
                Content.Arrange(new Rect(ptSecondGrid, sizeGrid));

                //print
                int k = i + 1;
                dlg.PrintVisual(Content, Title + " (Page " + k + ")");

                i++;
            }

            return i;
        }

        throw new PrintAborted(Properties.Resources.s_EN_Info_PrintingAborted);
    }

    #endregion
}

It prints the Datagrid or any other Control with the selected printer on multiple pages...

Usage:

        MessageBoxResult result = MessageBox.Show(Properties.Resources.s_EN_Question_Print, "Print", MessageBoxButton.YesNo, MessageBoxImage.Question);
        if (result == MessageBoxResult.Yes)
        {
            try
            {
                var border = VisualTreeHelper.GetChild(MyDataGrid, 0) as Decorator;
                if (border != null)
                {
                    var scrollViewer = border.Child as ScrollViewer;
                    if (scrollViewer != null)
                    {
                        scrollViewer.ScrollToTop();
                        scrollViewer.ScrollToLeftEnd();
                    }
                }

                Title = _initialTitle + " - " + Properties.Resources.s_EN_Info_Printing;

                var myPrinter = new UIPrinter{ Title = Title, Content = PrintGrid };
                int nbrOfPages = myPrinter.Print();

                Title = _initialTitle + " - " + Properties.Resources.s_EN_Info_PrintingDone + " (" + nbrOfPages + " Pages)";
            }
            catch (PrintAborted ex)
            {
                Title = _initialTitle + " - " + ex.Message;
            }
        }

EDIT: I placed my Datagrid on a simple grid containing a header control to have a header on my paper.

Denny Weinberg
  • 2,492
  • 1
  • 21
  • 34