2

I'm trying to implement a WPF Print function. It's working as long as the user doesnt want to print more than fits to one page. My Application enables the user to create xaml in runtime. Now i want to also enable him to print the xaml controls he created.

I have checked the total height of all xaml controls, devided by the pageheight and ceiled that number, so i know how many pages i have to print.

Next I'm creating a List of FrameworkElements for each page (see logic below) and store every List (each stands for one page) in an array.

At the end i want to create a preview which contains every page and enables the user to print all pages. In order to do that i have to put the pages together to a Document, but i dont know how. Please take a look at my code:

Package package = Package.Open("test.xps", FileMode.Create);

        // Create new xps document based on the package opened

        XpsDocument doc = new XpsDocument(package);

        // Create an instance of XpsDocumentWriter for the document

        XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);

        // Write the canvas (as Visual) to the document

        double height = element.ActualHeight;
        double width = element.ActualWidth;
        System.Windows.Controls.PrintDialog printDlg = new System.Windows.Controls.PrintDialog();
        Size pageSize = new Size(printDlg.PrintableAreaWidth, printDlg.PrintableAreaHeight);
        int pageCount = (int)Math.Ceiling(height / pageSize.Height);


        if (pageSize.Height < height) {
            var grid = element as Grid;
            var children = grid.Children;
            List<FrameworkElement>[] pages = new List<FrameworkElement>[pageCount-1];
            int i = 0;
            double currentHeight = 0;

            foreach (FrameworkElement c in children) {


                currentHeight += c.RenderSize.Height;


                if (currentHeight < pageSize.Height) {

                    pages[i] = new List<FrameworkElement>();
                    pages[i].Add(c);
                }
                else {
                    i++;
                    currentHeight = 0;
                    pages[i] = new List<FrameworkElement>();
                    pages[i].Add(c);
                }
            }
            for (int j = 0; j < pageCount; j++) {
                var collator = writer.CreateVisualsCollator();
                collator.BeginBatchWrite();
                foreach (FrameworkElement c in pages[j]) {


                    collator.Write(c);


                }
                collator.EndBatchWrite();
            }
        }


        doc.Close();

        package.Close();

        string filename = @"C:\Users\rzimmermann\Documents\Visual Studio 2012\Projects\MvvmLightPrintFunction\MvvmLightPrintFunction\bin\Debug\test.xps";

        DocumentViewer viewer = new DocumentViewer();

        doc = new XpsDocument(filename, FileAccess.Read);

        viewer.Document = doc.GetFixedDocumentSequence();

        Window ShowWindow = new Window();

        ShowWindow.Width = 400;

        ShowWindow.Height = 300;

        ShowWindow.Content = viewer;

        ShowWindow.Show();
1

2 Answers 2

1

@kenny is right you need to use the FixedPages. For a great tutorial pleas see: http://www.nbdtech.com/Blog/archive/2009/04/20/wpf-printing-part-2-the-fixed-document.aspx

As far as adding pages to a document you can do it like so:

doc.Pages.Add(page1Content);
doc.Pages.Add(page2Content);

//ect.

1
 ... PrintDialog dialog = new PrintDialog();

        //dialog.PrintVisual(this.scrollCheckCardinfo, "");
        Nullable<Boolean> print = dialog.ShowDialog();
        if (print == true)
        {
            Grid DynamicGrid = new Grid();
            DynamicGrid.Margin = new Thickness(100, 50, 0, 0);
            RowDefinition gridRow1 = new RowDefinition();
            gridRow1.Height = new GridLength(45);
            RowDefinition gridRow2 = new RowDefinition();
            DynamicGrid.RowDefinitions.Add(gridRow1);
            DynamicGrid.RowDefinitions.Add(gridRow2);
            TextBlock txtBlock1 = new TextBlock();
            txtBlock1.Text = "Printed by xyz " + DateTime.Now.ToString();
            txtBlock1.FontSize = 14;
            txtBlock1.FontWeight = FontWeights.Bold;
            txtBlock1.VerticalAlignment = VerticalAlignment.Top;

            Grid.SetRow(txtBlock1, 0);
            Grid.SetRow(this.scrollCheckCardinfo, 1);
            DynamicGrid.Children.Add(txtBlock1);
            DynamicGrid.Children.Add(CloneXaml(this.scrollCheckCardinfo));
            dialog.PrintVisual(DynamicGrid, "xyz");

        }...
     public static T CloneXaml<T>(T source)
    {
        string xaml = XamlWriter.Save(source);
        StringReader sr = new StringReader(xaml);
        XmlReader xr = XmlReader.Create(sr);
        return (T)XamlReader.Load(xr);
    }

this.scrollCheckCardinfo is a Grid.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.