Print dialog and print prewiew dialog for WPF

前端 未结 3 1306
既然无缘
既然无缘 2021-01-31 11:59

Is there a print dialog for WPF that is combinated whit a print preview dialog in WPF like Google Chrome or Word does?

At this moment I use a the print preview

相关标签:
3条回答
  • 2021-01-31 12:39

    Your requirements can be achieved in a number of ways, for instance, you can use the PrintDialog class. The following MSDN pages contains descriptions as well as some sample code:

    • WinForms: System.Windows.Forms.PrintDialog
    • WPF: System.Windows.Controls.PrintDialog (thanks to Bartosz)

    Alternatively it can be achieved via C# ,for example, consider the next code:

     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
                {
                }
            }
        }
    } 
    

    What it does: it actually prints the content of a visual into an XPS document. Then it loads the "printed" XPS document and displays it in a very simple XAML file that is stored as a string, rather than as a separate module, and loaded dynamically at runtime. The resulting Window has the DocumentViewer buttons: print, adjust-to-max-page-width, and so on.

    I also added some code to hide the Search box. See this answer to WPF: How can I remove the searchbox in a DocumentViewer? for how I did that.

    The effect is like this:

    The XpsDocument can be found in the ReachFramework dll and the XpsDocumentWriter can be found in the System.Printing dll both of which must be added as references to the project

    0 讨论(0)
  • 2021-01-31 12:41

    What you want to do, is to create an xpsDocument out from the content you want to print (a flowDocument) and use that XpsDocument to preview the content, for example let say you have the following Xaml, with a flowDocument that you want to print its content :

     <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>
    

    the flowDocument Sample is from Wpf tutorials site

    the print button Click event handler should looks like this :

     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; }
    

    so here you are mainly :

    • Creating an Xps document and storing it in printPreview.xps file,
    • Writing the FlowDocument content into that file,
    • passing the XpsDocument to the PrintWindow in which you will handle the preview and the print actions,

    here how the PrintWindow looks like :

    <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>
    

    and the code behind :

    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 
        }
    }
    

    the final result looks something like this

    enter image description here

    Ps: to use XpsDocument you should add a reference to System.Windows.Xps.Packaging namespace

    0 讨论(0)
  • 2021-01-31 13:01

    this is the sample solution for print prewiew : MainWindow.xaml

    <FlowDocumentScrollViewer>
            <FlowDocument x:Name="FD">
                <Paragraph>                    
                    <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" Click="Button_Click"></Button>
    

    MainWindow.xaml.cs

     private void Button_Click(object sender, RoutedEventArgs e)
            {
                //Fix the size of the document
                PrintDialog pd = new PrintDialog();
                FD.PageHeight = pd.PrintableAreaHeight;
                FD.PageWidth = pd.PrintableAreaWidth;
                FD.PagePadding = new Thickness(30);
                FD.ColumnGap = 0;
                FD.ColumnWidth = pd.PrintableAreaWidth;
    
                ////to print the document directly without print preview
                //IDocumentPaginatorSource dps = FD;
                //pd.PrintDocument(dps.DocumentPaginator, "flow doc");
    
                //Print preview the document before printing
                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 PrintPreview(Document);
                windows.ShowDialog();
            }
    

    PrintPreview.xaml

    <Window ........>        
        <DocumentViewer x:Name="PreviewD" />    
    </Window>
    

    PrintPreview.xaml.cs

    public partial class PrintPreview : Window
    {
        private FixedDocumentSequence _document;
        public PrintPreview(FixedDocumentSequence document)
        {
            _document = document;
            InitializeComponent();
            PreviewD.Document = document;
        }
    }
    
    0 讨论(0)
提交回复
热议问题