C# WPF的“打印”对话框和“打印预览”对话框

C# WPF的“打印”对话框和“打印预览”对话框,c#,wpf,xaml,printing,print-preview,C#,Wpf,Xaml,Printing,Print Preview,WPF是否有一个打印对话框与WPF中的打印预览对话框相结合,就像Google Chrome或Word那样 此时,我使用Windows窗体中的打印预览对话框。我还尝试使用它的WPF版本。但是WPF没有打印预览对话框或打印预览控件。这是我的代码: //To the top of my class file: using Forms = System.Windows.Forms; //in a methode on the same class: PageSettings setting = ne

WPF是否有一个打印对话框与WPF中的打印预览对话框相结合,就像Google Chrome或Word那样

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

//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软件包,但没有找到真正好的软件包。

您的需求可以通过多种方式实现,例如,您可以 使用
打印对话框
类。以下MSDN页面包含说明以及一些示例代码:

  • WinForms:
  • WPF:(感谢)
可以通过C语言实现,例如,考虑下一个代码:

 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
            {
            }
        }
    }
} 
private string\u previewWindowXaml=
@"
";
内部审核(字符串标题)
{
字符串文件名=System.IO.Path.GetRandomFileName();
FlowDocumentScrollViewer视觉=(FlowDocumentScrollViewer)(_parent.FindName(“fdsv1”));
尝试
{
//编写XPS文档
使用(XpsDocument doc=new XpsDocument(文件名,FileAccess.ReadWrite))
{
XpsDocumentWriter=XpsDocument.CreateXpsDocumentWriter(doc);
写作(视觉);
}
//将XPS文档读入动态生成的
//预览窗口
使用(XpsDocument doc=新XpsDocument(文件名,FileAccess.Read))
{
FixedDocumentSequence fds=doc.GetFixedDocumentSequence();
字符串s=\u previewWindowXaml;
s=s.Replace(“@@TITLE”,TITLE.Replace(“”,“&apos;”));
使用(var reader=new System.Xml.XmlTextReader(新的StringReader)))
{
窗口预览=System.Windows.Markup.XamlReader.Load(reader)as Window;
DocumentViewer dv1=LogicalTreeHelper.FindLogicalNode(预览,“dv1”)作为DocumentViewer;
dv1.文件=作为IDocumentPaginatorSource的fds;
preview.ShowDialog();
}
}
}
最后
{
if(File.Exists(fileName))
{
尝试
{
删除(文件名);
}
抓住
{
}
}
}
} 
它的功能:它实际上是将可视内容打印到XPS文档中。然后,它加载“打印的”XPS文档,并将其显示在一个非常简单的XAML文件中,该文件存储为字符串,而不是单独的模块,并在运行时动态加载。生成的窗口具有DocumentViewer按钮:打印、调整为最大页面宽度等

我还添加了一些代码来隐藏搜索框。看看我是怎么做到的

效果是这样的:


XpsDocument可以在ReachFramework dll中找到,XpsDocumentWriter可以在系统中找到。打印dll必须作为项目的引用添加这两个dll,您要做的是从要打印的内容(一个
流程文档
)中创建一个
XpsDocument
)并使用该
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>
所以你们主要是:

  • 创建Xps文档并将其存储在printPreview.Xps文件中
  • 流程文档
    内容写入该文件
  • XpsDocument
    传递到
    print窗口
    处理预览和打印操作
下面是
打印窗口的外观:

<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>
最终的结果是这样的


备注:要使用XpsDocument,您应该添加对以下内容的引用:

这是打印预览的示例解决方案: 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>
PrintPreview.xaml

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

您能将
PrintPreviewDialog
PrintPreviewDialog
组合起来吗?就像Google Chrome或Word一样。WPF
PrintDialog
类允许预览什么?看看这里,这样就没有办法用标准化的打印对话框实现了吗?这很好,可能最好使用内存流而不是XPS渲染文件。。。(删除对文件系统的依赖关系)
<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>
 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();
        }
<Window ........>        
    <DocumentViewer x:Name="PreviewD" />    
</Window>
public partial class PrintPreview : Window
{
    private FixedDocumentSequence _document;
    public PrintPreview(FixedDocumentSequence document)
    {
        _document = document;
        InitializeComponent();
        PreviewD.Document = document;
    }
}