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?
À 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.
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:
FlowDocument
dans ce fichier,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
Ps: pour utiliser XpsDocument, vous devez ajouter une référence à espace de noms System.Windows.Xps.Packaging
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("'", "'"));
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:
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