none
Stampare in wpf RRS feed

  • Domanda

  • Ciao a tutti potreste consigliarmi cosa utilizzare per stampare dei documenti, per creare un layout di stampa su c# wpf ? 

    un esempio potrebbe essere stampare una Documento di trasporto, dati derivanti da un  da un database  in un oggetto DDT.

    (Escludo SAP Crystal Reports perchè mi sta creando molti problemi per il funzionamento)

    grazie in anticipo a tutti

     


    fabio miceli

    mercoledì 12 febbraio 2020 20:27

Risposte

  • ma alla prima chiamata però deve agire correttamente ?!


    fabio miceli

    Quello che mandi in stampa è quello dell'ultima chiamata che non ha le impostazioni di pagina e colonna.

    Dovresti fare:

    FlowDocument fd = CreateFlowDocument10();

    e poi usare fd.


    • Contrassegnato come risposta Fabio Miceli giovedì 9 aprile 2020 21:35
    giovedì 9 aprile 2020 15:03

Tutte le risposte

  • Ciao a tutti potreste consigliarmi cosa utilizzare per stampare dei documenti, per creare un layout di stampa su c# wpf ? 

    ...

     


    fabio miceli

    http://www.nullskull.com/a/1378/wpf-printing-and-print-preview.aspx

    sabato 15 febbraio 2020 08:10
  • Ciao BlueLed,

    Mandando in stampa una Grid mi succede che a fine stampa mi sposta la Grid nella parte superiore della Window,

    in sostanza si sovrappone al ToolBarTray che gli ho dato un altezza di 35.

    come posso fare per ripristinare a fine stampa la posizione originale della Grid (sotto ToolBarTray) ?

    questo e il  codice con cui mando in stampa:

                 
                if ((bool)PrintdDDT.ShowDialog().GetValueOrDefault())
                {
                    Size pageSize = new Size(PrintdDDT.PrintableAreaWidth, PrintdDDT.PrintableAreaHeight);
                    grd_main.Measure(pageSize);
                    grd_main.Arrange(new Rect(0, 0, pageSize.Width, pageSize.Height));
                    PrintdDDT.PrintVisual(grd_main, Title);
                  
                }





    fabio miceli






    domenica 5 aprile 2020 16:11
  • Prova passando vecchie dimensioni e rettangolo a Measure ed Arrange dopo la stampa.
    lunedì 6 aprile 2020 08:40
  • ho risolto disattivando verticalscrollbar prima della stampa

    e riattivandola dopo:

     ScrollViewer.SetVerticalScrollBarVisibility(lv_Elements, ScrollBarVisibility.Visible);


    fabio miceli

    martedì 7 aprile 2020 10:20
  • Nella Grid che mando in stampa ho una ListView:

    mandando in stampa la Grid non mi stampa tutti gli elementi inseriti nella ListView ma soltanto quelli vusualizzati a schermo.

                 ScrollViewer.SetVerticalScrollBarVisibility(lv_Elements, ScrollBarVisibility.Hidden);
    
                if ((bool)PrintdDDT.ShowDialog().GetValueOrDefault())
                {
                    Size pageSize = new Size(PrintdDDT.PrintableAreaWidth, PrintdDDT.PrintableAreaHeight);
                    grd_main.Measure(pageSize);
                    grd_main.Arrange(new Rect(0, 0, pageSize.Width, pageSize.Height));
                    PrintdDDT.PrintVisual(grd_main, Title);
                    ScrollViewer.SetVerticalScrollBarVisibility(lv_Elements, ScrollBarVisibility.Visible);
                }
    


    Come posso fare per mandare in stampa la lista completa ? (rispettando l'altezza del layout di stampa)


    fabio miceli


    martedì 7 aprile 2020 10:24
  • Se devi stampare una lista, puoi creare un FlowDocument, riempirlo con gli elementi della lista e stamparlo.

    Qui mostra come stampare con un FlowDocument:

    https://www.c-sharpcorner.com/uploadfile/mahesh/printing-in-wpf/

    martedì 7 aprile 2020 10:51
  • Ciao BlueLed grazie per il suggerimento:

    ho creato il mio FlowDocument con la ListView in XAML con questo codice:

            <FlowDocumentScrollViewer  Margin="0,30,0,0">
                <FlowDocument x:Name="test_flow_print">
                    <Paragraph FontSize="36" Margin="0">Users</Paragraph>
                    <Paragraph FontStyle="Italic" TextAlignment="Left" FontSize="14" Foreground="Gray">Here's a list of our users, inside our FlowDocument, in a completely interactive ListView control!</Paragraph>
                    <BlockUIContainer>
                        <ListView x:Name="lv_test" BorderThickness="0" >
                            <ListView.View>
                                <GridView>
                                    <GridViewColumn Header="Code" DisplayMemberBinding="{Binding Code}" Width="150" />
                                    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="75" />
                                </GridView>
                            </ListView.View>
                        </ListView>
                    </BlockUIContainer>
                    <Paragraph FontStyle="Italic" TextAlignment="Left" FontSize="14" Foreground="Gray">More content can go here...</Paragraph>
                </FlowDocument>
            </FlowDocumentScrollViewer>
    

    Ma perchè quando finisce di stampare   pulisce la Window(diventa Bianca), e se interagisco con l'applicazione si blocca e va in eccezione ???

    System.NullReferenceException: 'Riferimento a un oggetto non impostato su un'istanza di oggetto.'

    MS.Internal.PtsHost.FlowDocumentPage.UpdateViewport(ref MS.Internal.PtsHost.UnsafeNativeMethods.PTS.FSRECT, bool)
    MS.Internal.Documents.FlowDocumentFormatter.Arrange(System.Windows.Size, System.Windows.Rect)
    MS.Internal.Documents.FlowDocumentView.ArrangeOverride(System.Windows.Size)
    System.Windows.FrameworkElement.ArrangeCore(System.Windows.Rect)
    System.Windows.UIElement.Arrange(System.Windows.Rect)
    System.Windows.ContextLayoutManager.UpdateLayout()
    System.Windows.ContextLayoutManager.UpdateLayoutCallback(object)
    System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork()
    System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
    System.Windows.Media.MediaContext.RenderMessageHandlerCore(object)
        ...
        [Stack di chiamate troncato]


    fabio miceli

    martedì 7 aprile 2020 20:38
  • Si aspetta l'ItemsSource ?
    • Modificato BlueLed martedì 7 aprile 2020 20:59
    martedì 7 aprile 2020 20:59
  • ciao

    ho risolto disattivando la scroll di FlowDocumentScrollViewer

     ScrollViewer.SetVerticalScrollBarVisibility(scroll1, ScrollBarVisibility.Hidden);

    così non mi da più problemi.

    però mi rimane un problema fondamentale, mandando una lista di più pagine (ad esempio 200 elementi) mi mette in stampa fino a 48 elementi, (soltanto 3 pagine) la prima pagina con  l'intestazione, la seconda pagina correttamente piena di elementi ma la terza  il footer del documento cioè i dati di fine pagina


    fabio miceli

    martedì 7 aprile 2020 22:18
  • Stai stampando con PrintDocument o stampi ancora con PrintVisual?
    martedì 7 aprile 2020 22:31
  •             PrintdDDT = new System.Windows.Controls.PrintDialog();
    
                ScrollViewer.SetVerticalScrollBarVisibility(scroll1, ScrollBarVisibility.Hidden);
     
                if ((bool)PrintdDDT.ShowDialog().GetValueOrDefault())
                    {
    
                        PrintDialog pd = new PrintDialog();
                    flow_print.PageHeight = pd.PrintableAreaHeight;
                    flow_print.PageWidth = pd.PrintableAreaWidth;
                        flow_print.PagePadding = new Thickness(50);
                        flow_print.ColumnGap = 0;
                        flow_print.ColumnWidth = pd.PrintableAreaWidth;
    
                        IDocumentPaginatorSource dps = flow_print;
    
                        Size pageSize = new Size(PrintdDDT.PrintableAreaWidth, PrintdDDT.PrintableAreaHeight);
                        lv_test.Measure(pageSize);
                        lv_test.Arrange(new Rect(0, 0, pageSize.Width, pageSize.Height));
    
    
                        pd.PrintDocument(dps.DocumentPaginator, "flow doc");
    
                    ScrollViewer.SetVerticalScrollBarVisibility(scroll1, ScrollBarVisibility.Visible);
    
    stampo con  printdocument

    fabio miceli

    martedì 7 aprile 2020 22:39
  • Il FlowDocument ha le proprietà PageWidth e PageHeight. Measure e Arrange non dovrebbero essere necessari, a cosa ti servono?
    martedì 7 aprile 2020 23:08
  • Si infatti se li elimino non cambia nulla

    fabio miceli

    martedì 7 aprile 2020 23:24
  • cosa potrebbe essere.......non riesco a capire...eppure e come se vedesse che ci sono molti elementi nella lista perchè mi da già più di una pagina

    fabio miceli

    martedì 7 aprile 2020 23:26
  • Se metti le stringhe da stampare in un componente lista, probabilmente viene stampata solo la parte visibile attraverso il rettangolo del componente. Prova mettendo gli elementi direttamente dentro il documento tramite paragrafi e run come nell'esempio che ti avevo dato. Oppure usando gli elementi List e ListItem come mostra qui:

    https://docs.microsoft.com/it-it/dotnet/framework/wpf/advanced/flow-document-overview



    • Modificato BlueLed mercoledì 8 aprile 2020 06:07
    mercoledì 8 aprile 2020 06:03
  • Non lo so... non riesco a stampare si blocca  la stampa mi apre l'anteprima di stampa e non va più avanti...

    anche senza l'anteprima di stampa non va.

    La lista nel content della Page  la visualizza correttamente.

            private void Page_Loaded(object sender, RoutedEventArgs e)
            {
                Paragraph myParagraph = new Paragraph();
    
                // Add some Bold text to the paragraph
                myParagraph.Inlines.Add(new Bold(new Run("Some bold text in the paragraph.")));
    
                // Add some plain text to the paragraph
                myParagraph.Inlines.Add(new Run(" Some text that is not bold."));
    
                // Create a List and populate with three list items.
                List myList = new List();
    
                for (int x = 1; x <= 200; x++)
                {
                    // First create paragraphs to go into the list item.
                    Paragraph paragraphListItem1 = new Paragraph(new Run("ListItem " + x.ToString()));
                    // Add ListItems with paragraphs in them.
                    myList.ListItems.Add(new ListItem(paragraphListItem1));
                }
    
                // Create a FlowDocument with the paragraph and list.
                FlowDocument myFlowDocument = new FlowDocument();
                myFlowDocument.Blocks.Add(myParagraph);
                myFlowDocument.Blocks.Add(myList);
    
                // Add the FlowDocument to a FlowDocumentReader Control
                myFlowDocumentReader = new FlowDocumentReader();
                myFlowDocumentReader.Document = myFlowDocument;
    
    
                this.Content = myFlowDocumentReader;
    
    
                System.Windows.Controls.PrintDialog PrintdDDT = new System.Windows.Controls.PrintDialog();
                if ((bool)PrintdDDT.ShowDialog().GetValueOrDefault())
                {
    
    
                    PrintDialog pd = new PrintDialog();
                    myFlowDocument.PageWidth = pd.PrintableAreaWidth;
                    myFlowDocument.PageHeight = pd.PrintableAreaHeight;
                    myFlowDocument.PageWidth = pd.PrintableAreaWidth;
                    myFlowDocument.PagePadding = new Thickness(50);
                    myFlowDocument.ColumnGap = 0;
                    myFlowDocument.ColumnWidth = pd.PrintableAreaWidth;
    
                    IDocumentPaginatorSource dps = myFlowDocument;
                    pd.PrintDocument(dps.DocumentPaginator, "flow doc");
    
    
                }
    
                //myFlowDocumentReader.Print();
    
            }
    


    fabio miceli

    mercoledì 8 aprile 2020 12:16
  • Il FlowDocumentReader a che ti serve? E perché apri il PrintDialog in Page_Loaded? Se metti insieme troppe cose poi diventa difficile capire dove sta il problema.


    mercoledì 8 aprile 2020 13:42
  • ho eliminato FlowDocumentReader e messo printdialog in un button all'interno del Paragraph per mandare in stampa ma non e cambiato niente

    fabio miceli

    mercoledì 8 aprile 2020 14:29
  •             myFlowDocument = new FlowDocument();
                // Create a FlowDocument  
                //FlowDocument doc = new FlowDocument();
                // Create a Section  
                Section sec = new Section();
                // Create first Paragraph  
                Paragraph p1 = new Paragraph();
                // Create and add a new Bold, Italic and Underline  
                Bold bld = new Bold();
    
                bld.Inlines.Add(new Run("First Paragraph"));
    
                Paragraph btparag = new Paragraph();
                Button btn = new Button();
                btn.Name = "bt_1";
                btn.Content = "Stampa";
                btn.Click += btn1_Click;
                btparag.Inlines.Add(btn);
                sec.Blocks.Add(btparag);
    
    
                Italic italicBld = new Italic();
                italicBld.Inlines.Add(bld);
                Underline underlineItalicBld = new Underline();
                underlineItalicBld.Inlines.Add(italicBld);
                // Add Bold, Italic, Underline to Paragraph  
                p1.Inlines.Add(underlineItalicBld);
                // Add Paragraph to Section  
                sec.Blocks.Add(p1);
    
    
    
                for (int x = 1; x <= 50; x++)
                {
                    // First create paragraphs to go into the list item.
                    Paragraph paragraphListItem1 = new Paragraph(new Run("ListItem " + x.ToString()));
                    // Add ListItems with paragraphs in them.
                    //myList.ListItems.Add(new ListItem(paragraphListItem1));
                    sec.Blocks.Add(paragraphListItem1);
    
                }
    
                // Add Section to FlowDocument  
                myFlowDocument.Blocks.Add(sec);
    
                
    
                this.Content = myFlowDocument;
    


    fabio miceli

    mercoledì 8 aprile 2020 14:31
  • ho eliminato FlowDocumentReader e messo printdialog in un button all'interno del Paragraph per mandare in stampa ma non e cambiato niente

    fabio miceli

    Vedi se si blocca anche stampando un documento semplice come questo:

    FlowDocument doc = new FlowDocument(new Paragraph(new Run("1 2 3 prova")));

    mercoledì 8 aprile 2020 14:55
  • OK ho disinstallato i driver della stampante e reinstallato.

    adesso dall' esempio di questo link che mi hai postato funziona.

    https://www.c-sharpcorner.com/uploadfile/mahesh/printing-in-wpf/

    ho anche messo un ciclo di 200 elementi e mi da tutte le pagine.

    non ho capito cosa gli era preso perchè altri documenti word li stampava !!


    fabio miceli

    mercoledì 8 aprile 2020 16:27
  • Questo codice mi da la stampa della collezione con due ListView per ogni pagina,

    a me serve che mi dia solo un ListView su più pagine:

    potresti consigliarmi come modificarlo per ottenere ciò che serve a me....

            private FlowDocument PrintList5()
            {
    
                List<DDT> ddts = new List<DDT>();
                for (int x = 1; x <= 120; x++)
                {
                    DDT ddt = new DDT
                    {
                        Numero = "Numero " + x.ToString(),
                        Note = "Nota " + x.ToString()
                    };
                    ddts.Add(ddt);
                }
    
    
                FlowDocument doc = new FlowDocument();
                for (int i = 0; i < ddts.Count; i += 40)
                {
                    var list = (from c in ddts
    
                                select c).Skip(i).Take(40);
                    ListView l = new ListView();
                    l.ItemsSource = list;
                    GridView g = new GridView();
                    GridViewColumn firstNameColumn = new GridViewColumn() { Header = "Numero", DisplayMemberBinding = new Binding("Numero"), Width = 200 };
                    GridViewColumn lastNameColumn = new GridViewColumn()
                    {
                        Header = "Nota",
                        DisplayMemberBinding = new Binding("Note"),
                        Width = 200
                    };
                    g.Columns.Add(firstNameColumn);
                    g.Columns.Add(lastNameColumn);
    
    
                    l.View = g;
                    InlineUIContainer inlineContainer = new InlineUIContainer();
                    inlineContainer.Child = l;
                    Section customerReports = new Section();
                    customerReports.Blocks.Add(new Paragraph(inlineContainer));
                    doc.Blocks.Add(customerReports);
                }
                return doc;
            }
    
    


    fabio miceli

    mercoledì 8 aprile 2020 18:26
  • Questo codice mi da la stampa della collezione con due ListView per ogni pagina,

    a me serve che mi dia solo un ListView su più pagine:

    potresti consigliarmi come modificarlo per ottenere ciò che serve a me....

    ...

    fabio miceli

    Devi stampare la ListView stessa oppure la lista degli elementi come prima?

    mercoledì 8 aprile 2020 21:06
  • Ciao in pratica quello che devo stampare è un documento di trasporto:

    che in testa alla pagina (o la prima pagina) i dati del cedente e del cessionario, in coda alla pagina i dati del DDT (ossia totale colli e firma).


    se gli elementi della ListView superano la lunghezza della pagina mi deve stampare tante pagine quante ne bastano per tutta la lista.

    la prima pagina solo con intestazione e ultima pagina con i dati del ddt

    NB: Questo se va non tutto in una pagina


    fabio miceli

    mercoledì 8 aprile 2020 21:19
  • Perché vuoi usare la Listview? Con la Listview hai già osservato che ti stampa soltanto gli elementi visibili, perché non usi il ciclo dove aggiungi gli elementi uno ad uno come prima?
    mercoledì 8 aprile 2020 21:46
  • Non ci sto capendo piu niente...perchè mi stampa due colonne per pagina ?

                FlowDocument myFlowDocument = new FlowDocument();
    
                // Create a FlowDocument  
                //FlowDocument doc = new FlowDocument();
                // Create a Section  
                Section sec = new Section();
                // Create first Paragraph  
                Paragraph p1 = new Paragraph();
                // Create and add a new Bold, Italic and Underline 
                for(int x = 1;x<=200; x++)
                {
                    Bold bld = new Bold();
                    bld.Inlines.Add(new Run("First Paragraph"+x.ToString()+"\n"));
                    Italic italicBld = new Italic();
                    italicBld.Inlines.Add(bld);
                    Underline underlineItalicBld = new Underline();
                    underlineItalicBld.Inlines.Add(italicBld);
                    // Add Bold, Italic, Underline to Paragraph  
                    p1.Inlines.Add(underlineItalicBld);
    
                    // Add Paragraph to Section  
                    sec.Blocks.Add(p1);
                    // Add Section to FlowDocument  
                    myFlowDocument.Blocks.Add(sec);
                }
    


    fabio miceli

    mercoledì 8 aprile 2020 23:20
  • Non ci sto capendo piu niente...perchè mi stampa due colonne per pagina ?

    fabio miceli
    Fai la colonna, proprietà ColumnWidth, larga quanto la pagina, eventualmente imposta anche ColumnGap.
    giovedì 9 aprile 2020 06:06
  • Qualsiasi cosa cambio non succede nulla.

                PrintdDDT = new System.Windows.Controls.PrintDialog();
    
                if ((bool)PrintdDDT.ShowDialog().GetValueOrDefault())
                {
                    PrintDialog pd = new PrintDialog();
                    CreateFlowDocument10().PageHeight = pd.PrintableAreaHeight;
                    CreateFlowDocument10().PageWidth = pd.PrintableAreaWidth;
                    CreateFlowDocument10().PagePadding = new Thickness(50);
                    CreateFlowDocument10().ColumnGap = pd.PrintableAreaWidth;
                    CreateFlowDocument10().ColumnWidth = pd.PrintableAreaWidth;
    
                    IDocumentPaginatorSource dps = CreateFlowDocument10();
                    pd.PrintDocument(dps.DocumentPaginator, "flow doc");
                }

    Ho provato anche a creare il Paragraph in questo modo:

                Paragraph myParagraph = new Paragraph();
                // Add some Bold text to the paragraph
                myParagraph.Inlines.Add(new Bold(new Run("Some bold text in the paragraph.")));
                // Add some plain text to the paragraph
                myParagraph.Inlines.Add(new Run(" Some text that is not bold."));
                // Create a List and populate with three list items.
                List myList = new List();
                
                for (int x = 1; x <= 200; x++)
                {
                    // First create paragraphs to go into the list item.
                    Paragraph paragraphListItem1 = new Paragraph(new Run("ListItem " + x.ToString()));
                    // Add ListItems with paragraphs in them.
                     
                    myList.ListItems.Add(new ListItem(paragraphListItem1));
                }
    
                // Create a FlowDocument with the paragraph and list.
                FlowDocument myFlowDocument = new FlowDocument();
                myFlowDocument.Blocks.Add(myParagraph);
                myFlowDocument.Blocks.Add(myList);
    
                // Add the FlowDocument to a FlowDocumentReader Control
                FlowDocumentReader myFlowDocumentReader = new FlowDocumentReader();
                myFlowDocumentReader.Document = myFlowDocument;
                
    
                return   myFlowDocument;
    


    giovedì 9 aprile 2020 10:34
  • Mi stampa sempre due colonne su ogni pagina.

    potresti per favore impostarmi il codice in modo corretto ?

    (magari se riesci a fare qualche test......)

    (ci sto perdendo la testa non riesco)


    fabio miceli

    giovedì 9 aprile 2020 10:40
  • CreateFlowDocument10() è il metodo che crea il documento, giusto?

    Se ogni volta che vuoi accedere al documento usi CreateFlowDocument10(), hai l'effetto collaterale che ne crei uno nuovo ad ogni invocazione, quindi il documento che stai passando a PrintDocument non contiene le precedenti impostazioni di ampiezze e larghezze. CreateFlowDocument10() lo devi chiamare una volta soltanto.

    giovedì 9 aprile 2020 11:24
  • ma alla prima chiamata però deve agire correttamente ?!


    fabio miceli

    giovedì 9 aprile 2020 13:52
  • ma alla prima chiamata però deve agire correttamente ?!


    fabio miceli

    Quello che mandi in stampa è quello dell'ultima chiamata che non ha le impostazioni di pagina e colonna.

    Dovresti fare:

    FlowDocument fd = CreateFlowDocument10();

    e poi usare fd.


    • Contrassegnato come risposta Fabio Miceli giovedì 9 aprile 2020 21:35
    giovedì 9 aprile 2020 15:03
  • Evviva :)

    Adesso mi da la lista corretta, una colonna per pagina  perfetto

    Grazie infinite


    fabio miceli

    giovedì 9 aprile 2020 21:35