打印WPF的对话框和打印预览对话框

时间:2015-04-27 09:42:14

标签: c# wpf xaml printing print-preview

是否有WPF的打印对话框与WPF中的打印预览对话框组合在一起,如Google Chrome或Word?

Like Google chrome does.

此时我使用Windows窗体中的打印预览对话框。我也尝试使用它的WPF版本。但WPF没有PrintPreviewDialogPrintPrewiewControl。这是我的代码:

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

我还搜索了一个NuGet包,但没有发现真的很好。

2 个答案:

答案 0 :(得分:12)

您要做的是从要打印的内容(xpsDocument)中创建flowDocument并使用XpsDocument预览内容,例如让假设您有以下 Xaml ,并且要flowDocument打印其内容:

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

flowDocument示例来自Wpf tutorials site

打印按钮Click事件处理程序应如下所示:

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

所以这里主要是:

  • 创建Xps文档并将其存储在printPreview.xps文件中
  • FlowDocument内容写入该文件,
  • XpsDocument传递给您所在的PrintWindow 处理预览和打印操作,

这里PrintWindow的样子如何:

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

和背后的代码:

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

最终结果看起来像这样

enter image description here

Ps:要使用XpsDocument,您应该添加对System.Windows.Xps.Packaging namespace

的引用

答案 1 :(得分:0)

这是打印预检的示例解决方案: 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;
    }
}