web-dev-qa-db-fra.com

Boîte de dialogue d'impression et boîte de dialogue d'aperçu avant impression pour WPF

Existe-t-il une boîte de dialogue d'impression pour WPF qui est combinée avec une boîte de dialogue d'aperçu avant impression dans WPF comme Google Chrome ou Word le fait?

Like Google chrome does.

À ce moment, j'utilise la boîte de dialogue d'aperçu avant impression des formulaires Windows. J'ai également essayé d'en utiliser la version WPF. Mais WPF n'a ni PrintPreviewDialog ni PrintPrewiewControl. Voici mon code:

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

J'ai également recherché un package NuGet mais rien n'a trouvé vraiment bon.

11
H. Pauwelyn

Ce que vous voulez faire, c'est créer un xpsDocument à partir du contenu que vous souhaitez imprimer (un flowDocument) et utiliser ce XpsDocument pour prévisualiser le contenu, par exemple laissez disons que vous avez le Xaml , avec un flowDocument que vous souhaitez imprimer son contenu:

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

l'exemple flowDocument provient de site de tutoriels Wpf

le bouton d'impression du gestionnaire d'événements Click devrait ressembler à ceci:

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

vous voici donc principalement:

  • Créer un document Xps et le stocker dans le fichier printPreview.xps,
  • Écriture du contenu FlowDocument dans ce fichier,
  • en passant le XpsDocument au PrintWindow dans lequel vous gérerez l'aperçu et les actions d'impression,

voici à quoi ressemble le 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>

et le code derrière:

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

le résultat final ressemble à ceci

enter image description here

Ps: pour utiliser XpsDocument, vous devez ajouter une référence à espace de noms System.Windows.Xps.Packaging

12
ELH

Vos besoins peuvent être atteints de plusieurs manières, par exemple, vous pouvez utiliser la classe PrintDialog. Les pages MSDN suivantes contiennent des descriptions ainsi que des exemples de code:

Alternativement, cela peut être réalisé via C #, par exemple, considérez le code suivant:

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

Ce qu'il fait: il imprime en fait le contenu d'un visuel dans un document XPS. Il charge ensuite le document XPS "imprimé" et l'affiche dans un fichier XAML très simple qui est stocké sous forme de chaîne plutôt que sous forme de module séparé et chargé dynamiquement au moment de l'exécution. La fenêtre résultante a les boutons DocumentViewer: imprimer, ajuster à la largeur de page max, etc.

J'ai également ajouté du code pour masquer la zone de recherche. Voir cette réponse à WPF: Comment puis-je supprimer la boîte de recherche dans un DocumentViewer? pour savoir comment j'ai fait cela.

L'effet est le suivant:

alt text

Le XpsDocument peut être trouvé dans la dll ReachFramework et le XpsDocumentWriter peut être trouvé dans la dll System.Printing qui doivent être ajoutées en tant que références au projet

3
Noam M