none
XPS Dokument aus WPF Controls erstellen RRS feed

  • Frage

  • Hallo,

    ich möchte aus WPF Controls ein WPF Dokument erstellen. Aus einem Control eine XPS Datei zu erstellen habe ich schon mal geschafft.

    Hier der Code dazu:

    string containerName = "output.xps";
    
    File.Delete(containerName);
    
    using (XpsDocument _xpsDocument = new XpsDocument(containerName, FileAccess.ReadWrite))
    {
           XpsDocumentWriter xpsdw = XpsDocument.CreateXpsDocumentWriter(_xpsDocument);
    
           xpsdw.Write(img);
    
           _xpsDocument.Close();
    }

    Ich möchte allerdings ein mehrseitiges Dokument erstellen. Auf jede XPS Seite ein anderes WPF Control.

    Außerdem weiß ich auch nicht wie man die größe eines XPS Dokuments bzw. einer XPS Seite festlegt.

    Das WPF Control sollte dann auf die Größe der festgelegten XPS Seite skaliert werden.

    Hoffe ihr könnt mir bei meinem Problem behilflich sein.

    Samstag, 20. März 2010 16:55

Antworten

  • Hallo Diesel83,

    Also, ich habe mal Dein Problem angepackt und bin auf dieVisualsToXpsDocument Klasse gekommen.

    Jetzt, da ich wusste dass diese Klasse in das XPS die Visual-Objekten in einzelne Seiten schreiben kann, musste ich die Liste der Visual-Objekten (die Steuerelemente die im Grid drinnen sind) erstellen. Das wird gemacht im Code mithilfe der VisualTreeEnumHelper Klasse die durch jedes Kind der Grid geht und sie in die Liste stopft.

    Habe in der Grid ein paar Steuerelemente aus der Toolbox gezogen und nachher den Code auf dem Knopf geschrieben um das „XPS drucken“ zu steuern.

    Am Ende habe ich die XPS Datei auf der Festplatte liegen die vier Seiten hat (für ein jedes Steuerelement aus der Grid).

    Der Code sieht wie folgt aus (Referenzen auf ReachFramework und System.Printing eingefügt):

    [XAML]

    <Window x:Class="WpfApplication1.Window1"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="Window1" Height="392" Width="406">
      <Grid Name="gridAutoDetails">
        <Button Height="23" Margin="104,0,99,64" Name="button1" VerticalAlignment="Bottom" Click="button1_Click">Button</Button>
        <CheckBox Height="16" Margin="34,36,124,0" Name="checkBox1" VerticalAlignment="Top">CheckBox</CheckBox>
        <ComboBox Height="23" Margin="76,75,82,0" Name="comboBox1" VerticalAlignment="Top" />
        <Ellipse Margin="84,131,100,123" Name="ellipse1" Stroke="Black" />
      </Grid>
    </Window>

     

    [C# Code Behind]

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Windows.Xps;
    using System.Windows.Xps.Packaging;
    using System.IO;
    
    namespace WpfApplication1
    
    {
    
      /// <summary>
      /// Interaktion Logik für Window1.xaml
      /// </summary>
    
      public partial class Window1 :Window
    
      {
    
        public Window1()
    
        {
          InitializeComponent();
        }
    
        private void button1_Click(object sender,RoutedEventArgs e)
    
        {
          string containerName = "C:\\Temp\\output.xps";
    
          using (XpsDocument _xpsDocument =new XpsDocument(containerName,FileAccess.ReadWrite))
    
          {
            XpsDocumentWriter xpsdw = XpsDocument.CreateXpsDocumentWriter(_xpsDocument);
            List<Visual> m_Visuals =VisualTreeEnumHelper.GetAllControls(gridAutoDetails);
            SaveVisuals(xpsdw, m_Visuals);
          }
    
        }
    
        //***************************************************************
    
        private void SaveVisuals(XpsDocumentWriter xpsdw,List<Visual> vc)
    
        {
          // Mehrere Visuals werden schreiben
          VisualsToXpsDocument vToXpsD = (VisualsToXpsDocument)xpsdw.CreateVisualsCollator();
    
          // Alle Visuals der Collection durchlaufen 
          foreach (Visual v in vc)
          {
            vToXpsD.Write(v);  //Jedes Visual wird in eine Seite geschreiben 
          }
    
          // Schreiben enden
          vToXpsD.EndBatchWrite();
    
        }
    
        //***************************************************************
    
     
    
        //***************************************************************
    
          //Helper Klasse für die VisualTree auflisten
    
          public class VisualTreeEnumHelper
          {
    
          private static List<Visual> _lst;
    
          public static List<Visual> GetAllControls(Visual vElementRoot)
          {
            _lst = new List<Visual>();
            EnumVisualTree(vElementRoot);
            return _lst;
          }
    
          private static void EnumVisualTree(Visual vElementRoot)
          {
            for (int intCounter = 0; intCounter <VisualTreeHelper.GetChildrenCount(vElementRoot); intCounter++)
            {
              //Kontrolle zugreifen (die Kinder)
              Visual child = (Visual)VisualTreeHelper.GetChild(vElementRoot, intCounter);
              //Die Kontrolle in die Liste einfügen
              _lst.Add(child);
              //Rekursiv - die KindsKinder :)
              //EnumVisualTree(child);
            }
    
          }
    
          }
      }
    
    }

     

     

    Schau Dir auch folgende Links an. Vielleicht findest Du auch noch andere interessante Wege wie man so etwas machen kann.

    FixedDocument / XPS Dokumentàhttp://msdn.microsoft.com/en-us/magazine/cc163664.aspx

    http://blogs.msdn.com/fyuan/archive/2007/03/10/convert-xaml-flow-document-to-xps-with-style-multiple-page-page-size-header-margin.aspx

    Dokumente in WPFàhttp://msdn.microsoft.com/en-us/library/ms748388.aspx

    http://stackoverflow.com/questions/502198/convert-wpf-xaml-control-to-xps-document

    Grüße und Erfolg,

    Robert

    Donnerstag, 15. April 2010 12:05
    Moderator

Alle Antworten

  • Hallo Diesel83,

    Mithilfe der PrintTicket-Klasse kannst Du die Einstellungen eines Druckauftrags definieren à http://msdn.microsoft.com/de-de/library/system.printing.printticket.aspx

    Code-Beispeil

                printButton.Click += delegate
                {
                    LocalPrintServer ps = new LocalPrintServer();
                    PrintQueue pq = ps.DefaultPrintQueue;
                    XpsDocumentWriter xpsdw = PrintQueue.CreateXpsDocumentWriter(pq);
                    PrintTicket pt = pq.UserPrintTicket;
                    if (xpsdw != null)
                    {
                        pt.PageOrientation = PageOrientation.Portrait;
                        PageMediaSize pageMediaSize = new PageMediaSize(this.ActualWidth, this.ActualHeight);
                        pt.PageMediaSize = pageMediaSize;
                        xpsdw.Write(container);
                    }
                };

     

    Grüße,

    Robert

    Donnerstag, 25. März 2010 10:18
    Moderator
  • Hallo Diesel83,

    Also, ich habe mal Dein Problem angepackt und bin auf dieVisualsToXpsDocument Klasse gekommen.

    Jetzt, da ich wusste dass diese Klasse in das XPS die Visual-Objekten in einzelne Seiten schreiben kann, musste ich die Liste der Visual-Objekten (die Steuerelemente die im Grid drinnen sind) erstellen. Das wird gemacht im Code mithilfe der VisualTreeEnumHelper Klasse die durch jedes Kind der Grid geht und sie in die Liste stopft.

    Habe in der Grid ein paar Steuerelemente aus der Toolbox gezogen und nachher den Code auf dem Knopf geschrieben um das „XPS drucken“ zu steuern.

    Am Ende habe ich die XPS Datei auf der Festplatte liegen die vier Seiten hat (für ein jedes Steuerelement aus der Grid).

    Der Code sieht wie folgt aus (Referenzen auf ReachFramework und System.Printing eingefügt):

    [XAML]

    <Window x:Class="WpfApplication1.Window1"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="Window1" Height="392" Width="406">
      <Grid Name="gridAutoDetails">
        <Button Height="23" Margin="104,0,99,64" Name="button1" VerticalAlignment="Bottom" Click="button1_Click">Button</Button>
        <CheckBox Height="16" Margin="34,36,124,0" Name="checkBox1" VerticalAlignment="Top">CheckBox</CheckBox>
        <ComboBox Height="23" Margin="76,75,82,0" Name="comboBox1" VerticalAlignment="Top" />
        <Ellipse Margin="84,131,100,123" Name="ellipse1" Stroke="Black" />
      </Grid>
    </Window>

     

    [C# Code Behind]

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Windows.Xps;
    using System.Windows.Xps.Packaging;
    using System.IO;
    
    namespace WpfApplication1
    
    {
    
      /// <summary>
      /// Interaktion Logik für Window1.xaml
      /// </summary>
    
      public partial class Window1 :Window
    
      {
    
        public Window1()
    
        {
          InitializeComponent();
        }
    
        private void button1_Click(object sender,RoutedEventArgs e)
    
        {
          string containerName = "C:\\Temp\\output.xps";
    
          using (XpsDocument _xpsDocument =new XpsDocument(containerName,FileAccess.ReadWrite))
    
          {
            XpsDocumentWriter xpsdw = XpsDocument.CreateXpsDocumentWriter(_xpsDocument);
            List<Visual> m_Visuals =VisualTreeEnumHelper.GetAllControls(gridAutoDetails);
            SaveVisuals(xpsdw, m_Visuals);
          }
    
        }
    
        //***************************************************************
    
        private void SaveVisuals(XpsDocumentWriter xpsdw,List<Visual> vc)
    
        {
          // Mehrere Visuals werden schreiben
          VisualsToXpsDocument vToXpsD = (VisualsToXpsDocument)xpsdw.CreateVisualsCollator();
    
          // Alle Visuals der Collection durchlaufen 
          foreach (Visual v in vc)
          {
            vToXpsD.Write(v);  //Jedes Visual wird in eine Seite geschreiben 
          }
    
          // Schreiben enden
          vToXpsD.EndBatchWrite();
    
        }
    
        //***************************************************************
    
     
    
        //***************************************************************
    
          //Helper Klasse für die VisualTree auflisten
    
          public class VisualTreeEnumHelper
          {
    
          private static List<Visual> _lst;
    
          public static List<Visual> GetAllControls(Visual vElementRoot)
          {
            _lst = new List<Visual>();
            EnumVisualTree(vElementRoot);
            return _lst;
          }
    
          private static void EnumVisualTree(Visual vElementRoot)
          {
            for (int intCounter = 0; intCounter <VisualTreeHelper.GetChildrenCount(vElementRoot); intCounter++)
            {
              //Kontrolle zugreifen (die Kinder)
              Visual child = (Visual)VisualTreeHelper.GetChild(vElementRoot, intCounter);
              //Die Kontrolle in die Liste einfügen
              _lst.Add(child);
              //Rekursiv - die KindsKinder :)
              //EnumVisualTree(child);
            }
    
          }
    
          }
      }
    
    }

     

     

    Schau Dir auch folgende Links an. Vielleicht findest Du auch noch andere interessante Wege wie man so etwas machen kann.

    FixedDocument / XPS Dokumentàhttp://msdn.microsoft.com/en-us/magazine/cc163664.aspx

    http://blogs.msdn.com/fyuan/archive/2007/03/10/convert-xaml-flow-document-to-xps-with-style-multiple-page-page-size-header-margin.aspx

    Dokumente in WPFàhttp://msdn.microsoft.com/en-us/library/ms748388.aspx

    http://stackoverflow.com/questions/502198/convert-wpf-xaml-control-to-xps-document

    Grüße und Erfolg,

    Robert

    Donnerstag, 15. April 2010 12:05
    Moderator