none
WPF Drucken! RRS feed

  • Frage

  • Auf der Suche nach Beispielen zum Drucken bin ich auf etwas gestoßen, dass wie folgt aufgebaut ist:

    // select printer and get printer settings
                PrintDialog pd = new PrintDialog();
                if (pd.ShowDialog() != true) return;
    
                // create a document
                FixedDocument document = new FixedDocument();
                document.DocumentPaginator.PageSize = new Size(pd.PrintableAreaWidth, pd.PrintableAreaHeight);
    
                // create a page
                FixedPage page1 = new FixedPage();
                page1.Width = document.DocumentPaginator.PageSize.Width;
                page1.Height = document.DocumentPaginator.PageSize.Height;
    
                // add some text to the page
                UserControl Page1Text = new UserControl();
                BendingTestDIN_V V = new BendingTestDIN_V();
                Page1Text.Content = V;
                page1.Margin = new Thickness(96);
                page1.Children.Add(Page1Text);
    
                // add the page to the document
                PageContent page1Content = new PageContent();
                ((IAddChild)page1Content).AddChild(page1);
                document.Pages.Add(page1Content);
    
                // and print
                pd.PrintDocument(document.DocumentPaginator, "My first document");  
    

    Hierbei bin ich schon mal soweit gekommen, dass ich eine View aus einer UserControl Drucken kann.
    Dabei instanziere ich die View neu, was wahrscheinlich nicht sehr Vorteilhaft ist (Druckansicht ist leer).

    Kann ich meine View als Statische Resource einbinden, sodass die geladenen Daten dann auch im Ausdruck sichtbar sind?
    Wie löse ich das Drucken meiner Views?

    Das Programm liegt im MVVM Pattern vor.


    Gruß

    Peter

    Wer grob fahrlässige Rechtschreibfehler findet, darf diese behalten ;0)
    Donnerstag, 6. Oktober 2011 12:57

Antworten

    • Als Antwort markiert Peter Sypek Dienstag, 11. Oktober 2011 10:52
    Dienstag, 11. Oktober 2011 10:02
    Beantworter
  • Ja ich denke.

    Unter Umständen muss du die Daten in der Listbox für den Druck filtern, oder ein anderes Layout überlegen,
    damit alle Daten dargestellt werden...

    • Als Antwort markiert Peter Sypek Dienstag, 11. Oktober 2011 11:19
    Dienstag, 11. Oktober 2011 11:12
    Beantworter
  • Du kannst die PrintVisual Methode benutzen um Views (Visuals) zu drucken.

    http://msdn.microsoft.com/de-de/library/system.windows.controls.printdialog.printvisual.aspx

     

    • Als Antwort markiert Peter Sypek Donnerstag, 6. Oktober 2011 15:05
    Donnerstag, 6. Oktober 2011 13:03
    Beantworter
  • Hallo Peter,

    schau mal in die Klassen "PrintTicket" und - wenn das nicht reicht - "PrintCapabilities" an. Der PrintDialog hat eine PrintTicket-Eigenschaft, die bereits vor dem Show()-Aufruf gesetzt werden kann (wie auch die PrintQueue) - als Vorgabe für den Dialog - oder danach (oder anstatt). Da Du das Papier per Einstellung nicht größer machen kannst, hilft Dir evtl. der PageScalingFactor.

    Die per PrintTicket gesetzten Eigenschaften müssen natürlich zum Drucker hinter der eingestellten PrintQueue passen.

    Gruß
    Jürgen

    • Als Antwort markiert Peter Sypek Donnerstag, 6. Oktober 2011 17:34
    Donnerstag, 6. Oktober 2011 17:10
  • Also ich bin jetzt ein ganzes stück weiter.

    Ich habe Hier => ClickMich!  ein Beispeil gefunden, welches mit FixedDocument arbeitet.
    Dabei packe ich meine Views in eine List<VisualBrush>. Aus jedem Item der Liste wird dann eine FixedPage generiert und letztendlich gedruckt.

     

    Dazu hier mein Code:

     private void Button_Click(object sender, RoutedEventArgs e)
            {
                PrintDialog pd = new PrintDialog();
                if (pd.ShowDialog() != true) return;
                FixedDocument document = CreateFixedDocument();
                pd.PrintDocument(document.DocumentPaginator, "My first document");
            }
    
            public FixedDocument CreateFixedDocument()
            {
                FixedDocument doc = new FixedDocument();
                doc.DocumentPaginator.PageSize = new Size(96 * 8.5, 96 * 11);
    
                List<VisualBrush> Views = new List<VisualBrush>();
                Views.Add(new VisualBrush(ICPDINFTR_V));
    
                foreach (var item in Views)
                {
                    PageContent page = new PageContent();
                    FixedPage fixedPage = CreateOneFixedPage(item);
                    ((IAddChild)page).AddChild(fixedPage);
    
                    doc.Pages.Add(page); 
                }           
                return doc;
            }
    
            private FixedPage CreateOneFixedPage(VisualBrush item)
            {
                FixedPage page = new FixedPage();
                page.Background = Brushes.White;
                page.Width = 96 * 8.5;
                page.Height = 96 * 11;
    
                VisualBrush vb = item;
                Rectangle rec = new Rectangle();
                rec.Width = page.Width;
                rec.Height = page.Height;
                rec.Fill = vb;
    
                Border b = new Border();
                b.BorderThickness = new Thickness(1);
                b.BorderBrush = Brushes.Black;
                b.Child = rec;
                FixedPage.SetLeft(b, 96);
                FixedPage.SetTop(b, 96);
                page.Children.Add((UIElement)b);
    
                Size sz = new Size(96 * 8.5, 96 * 11);
                page.Measure(sz);
                page.Arrange(new Rect(new Point(), sz));
                page.UpdateLayout();
    
                return page;
            }
    

    Das einzige Problem, dass ich jetzt noch habe ist, das die Views zu groß sind und nich auf eine Seite passen:
    Hier mein Ergebnis:

    Kann ich den Inhalt des Visuals skalieren?


    Gruß

    Peter

    Wer grob fahrlässige Rechtschreibfehler findet, darf diese behalten ;0)
    Dienstag, 11. Oktober 2011 09:05

Alle Antworten

  • Du kannst die PrintVisual Methode benutzen um Views (Visuals) zu drucken.

    http://msdn.microsoft.com/de-de/library/system.windows.controls.printdialog.printvisual.aspx

     

    • Als Antwort markiert Peter Sypek Donnerstag, 6. Oktober 2011 15:05
    Donnerstag, 6. Oktober 2011 13:03
    Beantworter
  • Kann ich den die Druckseite irgendwie Einrichten?

    Meine Seite ist etwas zu groß.


    Gruß

    Peter

    Wer grob fahrlässige Rechtschreibfehler findet, darf diese behalten ;0)
    Donnerstag, 6. Oktober 2011 16:00
  • Hallo Peter,

    schau mal in die Klassen "PrintTicket" und - wenn das nicht reicht - "PrintCapabilities" an. Der PrintDialog hat eine PrintTicket-Eigenschaft, die bereits vor dem Show()-Aufruf gesetzt werden kann (wie auch die PrintQueue) - als Vorgabe für den Dialog - oder danach (oder anstatt). Da Du das Papier per Einstellung nicht größer machen kannst, hilft Dir evtl. der PageScalingFactor.

    Die per PrintTicket gesetzten Eigenschaften müssen natürlich zum Drucker hinter der eingestellten PrintQueue passen.

    Gruß
    Jürgen

    • Als Antwort markiert Peter Sypek Donnerstag, 6. Oktober 2011 17:34
    Donnerstag, 6. Oktober 2011 17:10
  • Irgendwie bin ich noch nicht zu einem zufriedenstellendem Ergebnis gekommen.

    Meine Views sind alle recht groß und haben Scrollbalken.

    Hier wird immer nur der grade sichtbare Bereich gedruckt. Alles was ausserhalb des sichtbaren Bereiches ist wird verschluckt.

    Wie gehe ich denn am besten vor wenn ich die Views auf mehrere Seiten verteilen möchte?

    Hier mal eine Ansicht die Gedruckt werden soll (Inhalt des TabItems):


    Gruß

    Peter

    Wer grob fahrlässige Rechtschreibfehler findet, darf diese behalten ;0)

    • Bearbeitet Peter Sypek Montag, 10. Oktober 2011 07:44
    Montag, 10. Oktober 2011 07:42
  • Hallo Peter Sypek,

    Schau Dir mal die folgenden Links an. Vielleicht können sie Dir weiter helfen.

    Print all the content of a ListView ??

    Convert XAML Flow Document to XPS with Style (multiple page, page size, header, margin)

    Grüße,

    Robert

    Montag, 10. Oktober 2011 11:07
    Moderator
  • Hallo Peter Sypek,

    Schau Dir mal die folgenden Links an. Vielleicht können sie Dir weiter helfen.

    Print all the content of a ListView ??

    Convert XAML Flow Document to XPS with Style (multiple page, page size, header, margin)

    Grüße,

    Robert

    Grüß Dich Robert,

    das zweite Beispiel scheint vielversprechend zu sein,

    leider gibt es ein Konvertierungsproblem bei mir.

    DocumentPaginator paginator = ((IDocumentPaginatorSource)doc).DocumentPaginator;
                        // 8 inch x 6 inch, with half inch margin
                        paginator = new DocumentPaginatorWrapper(paginator, new Size(768, 676), new Size(48, 48));
    

    Der CocumentPaginatorWrapper kann nicht implizit izu einen DocumentPaginator Convertiert werden.

     


    Gruß

    Peter

    Wer grob fahrlässige Rechtschreibfehler findet, darf diese behalten ;0)
    Montag, 10. Oktober 2011 13:46
  • Also ich bin jetzt ein ganzes stück weiter.

    Ich habe Hier => ClickMich!  ein Beispeil gefunden, welches mit FixedDocument arbeitet.
    Dabei packe ich meine Views in eine List<VisualBrush>. Aus jedem Item der Liste wird dann eine FixedPage generiert und letztendlich gedruckt.

     

    Dazu hier mein Code:

     private void Button_Click(object sender, RoutedEventArgs e)
            {
                PrintDialog pd = new PrintDialog();
                if (pd.ShowDialog() != true) return;
                FixedDocument document = CreateFixedDocument();
                pd.PrintDocument(document.DocumentPaginator, "My first document");
            }
    
            public FixedDocument CreateFixedDocument()
            {
                FixedDocument doc = new FixedDocument();
                doc.DocumentPaginator.PageSize = new Size(96 * 8.5, 96 * 11);
    
                List<VisualBrush> Views = new List<VisualBrush>();
                Views.Add(new VisualBrush(ICPDINFTR_V));
    
                foreach (var item in Views)
                {
                    PageContent page = new PageContent();
                    FixedPage fixedPage = CreateOneFixedPage(item);
                    ((IAddChild)page).AddChild(fixedPage);
    
                    doc.Pages.Add(page); 
                }           
                return doc;
            }
    
            private FixedPage CreateOneFixedPage(VisualBrush item)
            {
                FixedPage page = new FixedPage();
                page.Background = Brushes.White;
                page.Width = 96 * 8.5;
                page.Height = 96 * 11;
    
                VisualBrush vb = item;
                Rectangle rec = new Rectangle();
                rec.Width = page.Width;
                rec.Height = page.Height;
                rec.Fill = vb;
    
                Border b = new Border();
                b.BorderThickness = new Thickness(1);
                b.BorderBrush = Brushes.Black;
                b.Child = rec;
                FixedPage.SetLeft(b, 96);
                FixedPage.SetTop(b, 96);
                page.Children.Add((UIElement)b);
    
                Size sz = new Size(96 * 8.5, 96 * 11);
                page.Measure(sz);
                page.Arrange(new Rect(new Point(), sz));
                page.UpdateLayout();
    
                return page;
            }
    

    Das einzige Problem, dass ich jetzt noch habe ist, das die Views zu groß sind und nich auf eine Seite passen:
    Hier mein Ergebnis:

    Kann ich den Inhalt des Visuals skalieren?


    Gruß

    Peter

    Wer grob fahrlässige Rechtschreibfehler findet, darf diese behalten ;0)
    Dienstag, 11. Oktober 2011 09:05
    • Als Antwort markiert Peter Sypek Dienstag, 11. Oktober 2011 10:52
    Dienstag, 11. Oktober 2011 10:02
    Beantworter
  • Ja.

    Schau dir mal folgenden Thread an:

    http://social.msdn.microsoft.com/Forums/de-DE/wpf/thread/39968080-40a1-4fbf-9ab7-03c37209efe7

     


    Super Marco,

    ein Transform brachte fast den richtigen Effekt.

    Ich habe mein VisualBrush einfach etwas kleiner skaliert.

    VisualBrush vb = item;
                vb.RelativeTransform = Transform.Identity;
                vb.RelativeTransform = new ScaleTransform(0.9, 0.8);
    

    So schaut das ganze dann aus:

     

    Jetzt stören nur noch die ScrollBalken in einer Listbox.

    Würde es eventuell schon helfen, wenn ich die Elemente direkt in der View etwas kleiner gestalte?


    Gruß

    Peter

    Wer grob fahrlässige Rechtschreibfehler findet, darf diese behalten ;0)
    Dienstag, 11. Oktober 2011 11:04
  • Ja ich denke.

    Unter Umständen muss du die Daten in der Listbox für den Druck filtern, oder ein anderes Layout überlegen,
    damit alle Daten dargestellt werden...

    • Als Antwort markiert Peter Sypek Dienstag, 11. Oktober 2011 11:19
    Dienstag, 11. Oktober 2011 11:12
    Beantworter
  • Ja ich denke.

    Unter Umständen muss du die Daten in der Listbox für den Druck filtern, oder ein anderes Layout überlegen,
    damit alle Daten dargestellt werden...

    Ich werde die Listbox mit den Scrollbalken einfach unter den restlichen Content setzen, und hoffen dass der Platz dann ausreicht.

    Dann gibt es noch einige Views in denen Bilder vorhanden sind, die dann auf der nächsten Seite gezeigt werden sollen.

    Da bin ich wohl noch eine Weile beschäftigt so ca. 30  Views in ein Druckbares Format zu überführen.

    Danke für die Hilfe!


    Gruß

    Peter

    Wer grob fahrlässige Rechtschreibfehler findet, darf diese behalten ;0)

    • Bearbeitet Peter Sypek Dienstag, 11. Oktober 2011 11:24
    Dienstag, 11. Oktober 2011 11:23