Benutzer mit den meisten Antworten
XPS Dokument aus WPF Controls erstellen

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.
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
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
- Als Antwort vorgeschlagen Robert BreitenhoferModerator Donnerstag, 15. April 2010 13:42
- Als Antwort markiert Robert BreitenhoferModerator Freitag, 16. April 2010 13:31
- Bearbeitet Robert BreitenhoferModerator Donnerstag, 13. Januar 2011 12:42 Formatierung
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
-
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
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
- Als Antwort vorgeschlagen Robert BreitenhoferModerator Donnerstag, 15. April 2010 13:42
- Als Antwort markiert Robert BreitenhoferModerator Freitag, 16. April 2010 13:31
- Bearbeitet Robert BreitenhoferModerator Donnerstag, 13. Januar 2011 12:42 Formatierung