web-dev-qa-db-ja.com

WPFの印刷ダイアログと印刷プレビューダイアログ

Google ChromeまたはWordのように、WPFの印刷プレビューダイアログと組み合わせたWPFの印刷ダイアログはありますか?

Like Google chrome does.

現時点では、Windowsフォームの印刷プレビューダイアログを使用しています。また、WPFバージョンの使用を試みています。ただし、WPFにはPrintPreviewDialogまたはPrintPrewiewControlがありません。これは私のコードです:

//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パッケージも検索しましたが、本当に良いものは見つかりませんでした。

11
H. Pauwelyn

やりたいことは、印刷するコンテンツ(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チュートリアルサイトからです

印刷ボタンの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コンテンツをそのファイルに書き込む、
  • XpsDocumentPrintWindowに渡して、プレビューと印刷アクションを処理します。

ここで、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名前空間への参照を追加する必要があります

12
ELH

要件はさまざまな方法で実現できます。たとえば、PrintDialogクラスを使用できます。次のMSDNページには、説明といくつかのサンプルコードが含まれています。

または、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
            {
            }
        }
    }
} 

機能:実際にビジュアルのコンテンツをXPSドキュメントに印刷します。次に、「印刷された」XPSドキュメントを読み込み、非常に単純なXAMLファイルに表示します。このファイルは、個別のモジュールとしてではなく文字列として格納され、実行時に動的に読み込まれます。結果のウィンドウにはDocumentViewerボタンがあります。印刷、max-to-page-widthの調整などです。

検索ボックスを非表示にするコードも追加しました。その方法については WPFへの回答:DocumentViewerで検索ボックスを削除するにはどうすればよいですか? を参照してください。

効果は次のとおりです。

alt text

XpsDocumentはReachFramework dllにあり、XpsDocumentWriterはSystem.Printing dllにあります。どちらもプロジェクトへの参照として追加する必要があります。

3
Noam M