2015-04-27 24 views
9

C'è una finestra di dialogo di stampa per WPF combinata con una finestra di anteprima di stampa in WPF come Google Chrome o Word?Finestra di dialogo di stampa e finestra di dialogo di anteprima di stampa per WPF

Like Google chrome does.

In questo momento io uso una finestra di dialogo l'anteprima di stampa da Windows Form. Ho anche provato a usare la versione WPF di esso. Ma WPF non ha PrintPreviewDialog o PrintPrewiewControl. Questo è il mio codice:

//To the top of my class file: 
using Forms = System.Windows.Forms; 

//in a methode on the same class: 
PageSettings setting = new PageSettings(); 
setting.Landscape = true; 

_document = new PrintDocument(); 
_document.PrintPage += _document_PrintPage; 
_document.DefaultPageSettings = setting ; 

Forms.PrintPreviewDialog printDlg = new Forms.PrintPreviewDialog(); 
printDlg.Document = _document; 
printDlg.Height = 500; 
printDlg.Width = 200; 

try 
{ 
    if (printDlg.ShowDialog() == Forms.DialogResult.OK) 
    { 
     _document.Print(); 
    } 
} 
catch (InvalidPrinterException) 
{ 
    MessageBox.Show("No printers found.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); 
} 

Ho anche cercato un pacchetto NuGet ma non è stato trovato nulla di veramente buono.

risposta

9

che cosa si vuole fare, è quello di creare un xpsDocument fuori dal contenuto che si desidera stampare (un flowDocument) e l'uso che XpsDocument per visualizzare in anteprima il contenuto, ad esempio diciamo che avete il seguente Xaml, con una flowDocument che si desidera stampare il suo contenuto:

<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="*"/> 
     <RowDefinition Height="Auto"/> 
    </Grid.RowDefinitions> 
    <FlowDocumentScrollViewer> 
     <FlowDocument x:Name="FD"> 
      <Paragraph> 
       <Image Source="http://www.wpf-tutorial.com/images/logo.png" Width="90" Height="90" Margin="0,0,30,0" /> 
       <Run FontSize="120">WPF</Run> 
      </Paragraph> 

      <Paragraph> 
       WPF, which stands for 
       <Bold>Windows Presentation Foundation</Bold> , 
       is Microsoft's latest approach to a GUI framework, used with the .NET framework. 
       Some advantages include: 
      </Paragraph> 

      <List> 
       <ListItem> 
        <Paragraph> 
         It's newer and thereby more in tune with current standards 
        </Paragraph> 
       </ListItem> 
       <ListItem> 
        <Paragraph> 
         Microsoft is using it for a lot of new applications, e.g. Visual Studio 
        </Paragraph> 
       </ListItem> 
       <ListItem> 
        <Paragraph> 
         It's more flexible, so you can do more things without having to write or buy new controls 
        </Paragraph> 
       </ListItem> 
      </List> 

     </FlowDocument> 
    </FlowDocumentScrollViewer>   
    <Button Content="Print" Grid.Row="1" Click="Button_Click"></Button> 
</Grid> 

il campione FlowDocument è da Wpf tutorials site

il pulsante Click gestore di eventi di stampa dovrebbe apparire come questo:

private void Button_Click(object sender, RoutedEventArgs e) 
    { 
if (File.Exists("printPreview.xps")) 
      { 
       File.Delete("printPreview.xps"); 
      } 
     var xpsDocument = new XpsDocument("printPreview.xps", FileAccess.ReadWrite); 
     XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(xpsDocument); 
     writer.Write(((IDocumentPaginatorSource)FD).DocumentPaginator);    
     Document = xpsDocument.GetFixedDocumentSequence(); 
     xpsDocument.Close(); 
     var windows = new PrintWindow(Document); 
     windows.ShowDialog(); 
    } 

public FixedDocumentSequence Document { get; set; } 

ecco siete principalmente:

  • Cre a un documento Xps e memorizzarlo in printPreview.file XPS,
  • scrivere il contenuto FlowDocument in quel file,
  • passando il XpsDocument alla PrintWindow in cui si gestire l'azioni anteprima di stampa e,

qui come il PrintWindow assomiglia:

<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="*"/> 
     <ColumnDefinition Width="1.5*"/> 
    </Grid.ColumnDefinitions> 
    <StackPanel> 
     <Button Content="Print" Click="Button_Click"></Button> 
     <!--Other print operations--> 
    </StackPanel> 
    <DocumentViewer Grid.Column="1" x:Name="PreviewD">    
    </DocumentViewer> 
</Grid> 

e il codice sottostante:

public partial class PrintWindow : Window 
{ 
    private FixedDocumentSequence _document; 
    public PrintWindow(FixedDocumentSequence document) 
    { 
     _document = document; 
     InitializeComponent(); 
     PreviewD.Document =document; 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     //print directly from the Xps file 
    } 
} 

il risultato finale simile a questa

enter image description here

Ps: per utilizzare XpsDocument si dovrebbe aggiungere un riferimento a System.Windows.Xps.Packaging namespace

+0

dai uno sguardo anche a http://stackoverflow.com/questions/2322064/how-can-i-produce-a -print-preview-of-a-flowdocument-in-a-wpf-application – Usama

+0

Quindi non c'è modo di farlo con una finestra di dialogo di stampa standardizzata? –

+0

Questo è buono, probabilmente meglio usare uno stream di memoria piuttosto che un file per il rendering XPS ... (rimuove la dipendenza dal file system) – CJBS

3

Le vostre esigenze possono essere raggiunte in diversi modi, ad esempio, è possibile utilizzare la classe PrintDialog. Le pagine che seguono MSDN contiene descrizioni e anche alcuni codice di esempio:

In alternativa, può essere raggiunto tramite C#, per esempio, considerare il prossimo codice:

private string _previewWindowXaml = 
    @"<Window 
     xmlns ='http://schemas.microsoft.com/netfx/2007/xaml/presentation' 
     xmlns:x ='http://schemas.microsoft.com/winfx/2006/xaml' 
     Title ='Print Preview - @@TITLE' 
     Height ='200' Width ='300' 
     WindowStartupLocation ='CenterOwner'> 
         <DocumentViewer Name='dv1'/> 
    </Window>"; 

internal void DoPreview(string title) 
{ 
    string fileName = System.IO.Path.GetRandomFileName(); 
    FlowDocumentScrollViewer visual = (FlowDocumentScrollViewer)(_parent.FindName("fdsv1")); 

    try 
    { 
     // write the XPS document 
     using (XpsDocument doc = new XpsDocument(fileName, FileAccess.ReadWrite)) 
     { 
      XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc); 
      writer.Write(visual); 
     } 

     // Read the XPS document into a dynamically generated 
     // preview Window 
     using (XpsDocument doc = new XpsDocument(fileName, FileAccess.Read)) 
     { 
      FixedDocumentSequence fds = doc.GetFixedDocumentSequence(); 

      string s = _previewWindowXaml; 
      s = s.Replace("@@TITLE", title.Replace("'", "&apos;")); 

      using (var reader = new System.Xml.XmlTextReader(new StringReader(s))) 
      { 
       Window preview = System.Windows.Markup.XamlReader.Load(reader) as Window; 

       DocumentViewer dv1 = LogicalTreeHelper.FindLogicalNode(preview, "dv1") as DocumentViewer; 
       dv1.Document = fds as IDocumentPaginatorSource; 


       preview.ShowDialog(); 
      } 
     } 
    } 
    finally 
    { 
     if (File.Exists(fileName)) 
     { 
      try 
      { 
       File.Delete(fileName); 
      } 
      catch 
      { 
      } 
     } 
    } 
} 

Che cosa fa: stampa effettivamente il contenuto di un'immagine in un XPS d DOCUMENTO. Quindi carica il documento XPS "stampato" e lo visualizza in un file XAML molto semplice che viene memorizzato come una stringa anziché come un modulo separato e caricato dinamicamente in fase di runtime. La finestra risultante ha i pulsanti di DocumentViewer: stampa, regola la larghezza della pagina e così via.

Ho anche aggiunto del codice per nascondere la casella di ricerca. Vedi this answer to WPF: How can I remove the searchbox in a DocumentViewer? per come l'ho fatto.

L'effetto è simile a questo:

alt text http://i48.tinypic.com/2hzkfat.jpg

Il XpsDocument può essere trovato nel dll ReachFramework e la XpsDocumentWriter può essere trovato nel System.Printing dll entrambi i quali va aggiunto come riferimenti progetto

+0

E si può combinare un 'PrintPreviewDialog' e un' PrintPreviewDialog'? Come Google Chrome o Word fa. –

+0

what's _parent e fdsv1 – AMH

+0

La classe 'PrintDialog' di WPF consente di visualizzare anteprime? –

Problemi correlati