web-dev-qa-db-fra.com

Convertir le contrôle WPF (XAML) en document XPS

Puis-je prendre un contrôle WPF (XAML) existant, le lier à des données et le transformer en un document XPS qui peut être affiché et imprimé à l'aide de la visionneuse de documents WPF XPS? Si c'est le cas, comment? Sinon, comment dois-je faire le "reporting" dans WPF en utilisant XPS/PDF/etc?

Fondamentalement, je veux prendre un contrôle WPF existant, le lier à des données pour y entrer des données utiles, puis le rendre imprimable et enregistrable pour l'utilisateur final. Idéalement, la création du document se ferait en mémoire et n'atteindrait pas le disque à moins que l'utilisateur n'ait spécifiquement enregistré le document. Est-ce faisable?

46
Scott

En fait, après avoir joué avec des tas d'échantillons différents, qui sont tous incroyablement compliqués et nécessitent l'utilisation de rédacteurs de documents, de conteneurs, de files d'attente d'impression et de tickets d'impression, j'ai trouvé un article d'Eric Sinks sur Impression dans WPF
Le code simplifié ne fait que 10 lignes

public void CreateMyWPFControlReport(MyWPFControlDataSource usefulData)
{
  //Set up the WPF Control to be printed
  MyWPFControl controlToPrint;
  controlToPrint = new MyWPFControl();
  controlToPrint.DataContext = usefulData;

  FixedDocument fixedDoc = new FixedDocument();
  PageContent pageContent = new PageContent();
  FixedPage fixedPage = new FixedPage();

  //Create first page of document
  fixedPage.Children.Add(controlToPrint);
  ((System.Windows.Markup.IAddChild)pageContent).AddChild(fixedPage);
  fixedDoc.Pages.Add(pageContent);
  //Create any other required pages here

  //View the document
  documentViewer1.Document = fixedDoc;
}

Mon exemple est assez simpliste, il n'inclut pas le dimensionnement et l'orientation de la page qui contient un ensemble de problèmes complètement différent qui ne fonctionne pas comme vous vous en doutez. Il ne contient pas non plus de fonctionnalité d'enregistrement, car MS semble avoir oublié d'inclure un bouton Enregistrer dans le visualiseur de documents.

La fonctionnalité de sauvegarde est relativement simple (et provient également de l'article d'Eric Sinks)

public void SaveCurrentDocument()
{
 // Configure save file dialog box
 Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
 dlg.FileName = "MyReport"; // Default file name
 dlg.DefaultExt = ".xps"; // Default file extension
 dlg.Filter = "XPS Documents (.xps)|*.xps"; // Filter files by extension

 // Show save file dialog box
 Nullable<bool> result = dlg.ShowDialog();

 // Process save file dialog box results
 if (result == true)
 {
   // Save document
   string filename = dlg.FileName;

  FixedDocument doc = (FixedDocument)documentViewer1.Document;
  XpsDocument xpsd = new XpsDocument(filename, FileAccess.ReadWrite);
  System.Windows.Xps.XpsDocumentWriter xw = XpsDocument.CreateXpsDocumentWriter(xpsd);
  xw.Write(doc);
  xpsd.Close();
 }
}

La réponse est donc Oui, vous pouvez prendre un contrôle WPF (XAML) existant, le lier à des données et le transformer en un document XPS - et ce n'est pas si difficile.

68
Scott