Manipulating the XAML code in memory to add additional rows for Document.Table
-
Monday, March 12, 2012 5:15 AM
Hi,
i got the below comments from Google:
/////*********
WPF does not directly support list data binding for Document.Table . By this we mean that there is no way to define a row template and then have the table automatically add a row for each data item in the data provider. We achieve this functionality by manipulating the XAML code in memory to add additional rows.
//////***********
So how can i achieve the above mentioned .
Regards,
sajith
All Replies
-
Monday, March 12, 2012 7:06 AM
I generate the complete document in memory (XML-Writer & memory stream) including any images or tables. You have to generate all necessary table statements manually. After finishing the generation of the document in memory, I use a deserializer to create a document object. Works good and gives me full control.
Greetings,
Chris -
Monday, March 12, 2012 8:17 AM
thanks chris,
can u please share the sample that u generated.
Regards,
sajith
-
Wednesday, March 14, 2012 6:29 AM
Hi sajith,
here is the code snippet (quite long one ...):
/// <summary> /// Schreibt den Inhalt einer Tabellen-Zelle /// </summary> /// <param name="xWriter">der XML-Writer</param> /// <param name="szContent">der Inhalt</param> private void XmlWriteTableCellContent(XmlWriter xWriter, string szContent) { XmlWriteTableCellContent(xWriter, szContent, TextAlignment.Left); } /// <summary> /// Schreibt den Inhalt einer Tabellen-Zelle /// </summary> /// <param name="xWriter">der XML-Writer</param> /// <param name="szContent">der Inhalt</param> /// <param name="txtAlign">die Ausrichtung</param> private void XmlWriteTableCellContent(XmlWriter xWriter, string szContent, TextAlignment txtAlign) { xWriter.WriteStartElement("TableCell"); xWriter.WriteStartElement("Paragraph"); if (txtAlign != TextAlignment.Left) xWriter.WriteAttributeString("TextAlignment", txtAlign.ToString()); xWriter.WriteString(szContent); xWriter.WriteEndElement(); xWriter.WriteEndElement(); } /// <summary> /// Schreibt den Inhalt einer Tabellen-Zelle /// </summary> /// <param name="xWriter">der XML-Writer</param> /// <param name="szContent">der Inhalt</param> /// <param name="txtAlign">die Ausrichtung</param> /// <param name="szBrush">Farbe als Text</param> private void XmlWriteTableCellContent(XmlWriter xWriter, string szContent, TextAlignment txtAlign, string szBrush) { xWriter.WriteStartElement("TableCell"); xWriter.WriteStartElement("Paragraph"); if (txtAlign != TextAlignment.Left) xWriter.WriteAttributeString("TextAlignment", txtAlign.ToString()); if (!string.IsNullOrWhiteSpace(szBrush)) xWriter.WriteAttributeString("Foreground", szBrush); xWriter.WriteString(szContent); xWriter.WriteEndElement(); xWriter.WriteEndElement(); } /// <summary> /// Schreibt den Inhalt einer Tabellen-Zelle mit einem Gruppierungseintrag /// </summary> /// <param name="xWriter">der XML-Writer</param> /// <param name="szColumnName">der Name der Gruppierungsspalte</param> /// <param name="szContent">der Inhalt</param> /// <param name="szAddedInfo">die Zusatzangaben</param> /// <param name="szColor">die Farbe für die Zusatzangaben</param> /// <param name="ColumnSpan">Anzahl der Spalten, die vereinigt werden sollen</param> private void XmlWriteTableCellGroupingContent(XmlWriter xWriter, string szColumnName, string szContent, string szAddedInfo, string szColor, int ColumnSpan) { xWriter.WriteStartElement("TableCell"); xWriter.WriteAttributeString("ColumnSpan", ColumnSpan.ToString()); xWriter.WriteStartElement("Paragraph"); // der vordere Anteil xWriter.WriteStartElement("Bold"); xWriter.WriteString(szColumnName + " : " + szContent); xWriter.WriteEndElement(); // der hintere Anteil xWriter.WriteStartElement("Italic"); xWriter.WriteStartElement("Run"); xWriter.WriteAttributeString("Foreground", szColor); xWriter.WriteString(szAddedInfo); xWriter.WriteEndElement(); xWriter.WriteEndElement(); // abschließen xWriter.WriteEndElement(); xWriter.WriteEndElement(); } /// <summary> /// Schreibt ein "TableColumn" Element /// </summary> /// <param name="xWriter">der XmlWriter</param> /// <param name="Width">die Breite</param> private void XmlTableColumn(XmlWriter xWriter, int Width) { xWriter.WriteStartElement("TableColumn"); xWriter.WriteAttributeString("Width", Width.ToString()); xWriter.WriteEndElement(); } /// <summary> /// Schreibt die Summe als Block unter die letzte Ausgabe im Dokument /// </summary> /// <param name="xw">der XmlWriter</param> /// <param name="xAbstand">linker Abstand</param> /// <param name="Width">gewünschte Breite</param> /// <param name="value">der Wert</param> /// <param name="showComplete">Flag, ob die Gesamtsumme angezeigt werden soll</param> /// <param name="sumValue">der Gesamtsummenwert</param> private void XmlWriteSumLine(XmlWriter xw, double xAbstand, double Width, decimal value, bool showComplete, decimal sumValue) { xw.WriteStartElement("BlockUIContainer"); xw.WriteStartElement("DockPanel"); xw.WriteAttributeString("Margin", xAbstand.ToString() + ",0,0,0"); xw.WriteStartElement("Rectangle"); xw.WriteAttributeString("DockPanel.Dock", "Top"); xw.WriteAttributeString("Fill", "Black"); xw.WriteAttributeString("Height", "0.5"); xw.WriteAttributeString("Width", (xAbstand + Width).ToString()); xw.WriteAttributeString("SnapsToDevicePixels", "True"); xw.WriteAttributeString("HorizontalAlignment", "Left"); xw.WriteEndElement(); xw.WriteStartElement("Rectangle"); xw.WriteAttributeString("DockPanel.Dock", "Top"); xw.WriteAttributeString("Margin", "0,2"); xw.WriteAttributeString("Fill", "Black"); xw.WriteAttributeString("Height", "0.5"); xw.WriteAttributeString("Width", (xAbstand + Width).ToString()); xw.WriteAttributeString("SnapsToDevicePixels", "True"); xw.WriteAttributeString("HorizontalAlignment", "Left"); xw.WriteEndElement(); xw.WriteStartElement("DockPanel"); xw.WriteAttributeString("DockPanel.Dock", "Top"); // <TextBlock> mit der Einzelsumme xw.WriteStartElement("TextBlock"); xw.WriteAttributeString("Width", (Width / 2).ToString()); xw.WriteAttributeString("FontSize", "10"); xw.WriteAttributeString("FontFamily", "Arial"); xw.WriteAttributeString("FontWeight", "Bold"); xw.WriteAttributeString("DockPanel.Dock", "Left"); xw.WriteAttributeString("HorizontalAlignment", "Left"); xw.WriteAttributeString("TextAlignment", "Right"); if (value < 0) xw.WriteAttributeString("Foreground", "Red"); xw.WriteAttributeString("Text", value.ToString("C")); xw.WriteEndElement(); if (showComplete) { // <TextBlock> mit der Gesamtsumme xw.WriteStartElement("TextBlock"); xw.WriteAttributeString("Width", (Width / 2).ToString()); xw.WriteAttributeString("DockPanel.Dock", "Left"); xw.WriteAttributeString("FontSize", "10"); xw.WriteAttributeString("FontFamily", "Arial"); xw.WriteAttributeString("TextAlignment", "Right"); xw.WriteAttributeString("HorizontalAlignment", "Left"); xw.WriteAttributeString("Text", "(Gesamt: " + sumValue.ToString("C") + ")"); xw.WriteEndElement(); } // </DockPanel> xw.WriteEndElement(); // </DockPanel> xw.WriteEndElement(); // </BlockUIContainer> xw.WriteEndElement(); } /// <summary> /// Schreibt die Summen als Block unter die letzte Ausgabe im Dokument (Warenbücher) /// </summary> /// <param name="xw">der XmlWriter</param> /// <param name="cDoc">das aktuelle Druckdokument</param> /// <param name="wert">Wert</param> /// <param name="wert7">Wert für geringbesteuerte Ware</param> /// <param name="skNetto">Skonto-Netto</param> /// <param name="sk19">Skonto (normal)</param> /// <param name="sk7">Skonto (vermindert)</param> private void XmlWarenbuchWriteSumLine(XmlWriter xw, SimFi7Document cDoc, decimal wert, decimal wert7, decimal skNetto, decimal sk19, decimal sk7) { decimal bezahlt = wert - skNetto - sk19 - sk7; int LastIndex = cDoc.ColumnWidths.Count - 1; double Margin2 = 0; // Zwischenraum berechnen for (int i = 2; i <= LastIndex - 6; ++i) Margin2 += (cDoc.ColumnWidths[i] + 5); xw.WriteStartElement("BlockUIContainer"); xw.WriteStartElement("DockPanel"); xw.WriteAttributeString("Margin", (5 + cDoc.ColumnWidths[0]).ToString() + ",0,0,0"); xw.WriteStartElement("Rectangle"); xw.WriteAttributeString("DockPanel.Dock", "Top"); xw.WriteAttributeString("Fill", "Black"); xw.WriteAttributeString("Height", "0.5"); xw.WriteAttributeString("SnapsToDevicePixels", "True"); xw.WriteEndElement(); xw.WriteStartElement("Rectangle"); xw.WriteAttributeString("DockPanel.Dock", "Top"); xw.WriteAttributeString("Margin", "0,2"); xw.WriteAttributeString("Fill", "Black"); xw.WriteAttributeString("Height", "0.5"); xw.WriteAttributeString("SnapsToDevicePixels", "True"); xw.WriteEndElement(); xw.WriteStartElement("DockPanel"); xw.WriteAttributeString("DockPanel.Dock", "Top"); // <TextBlock> mit der Einzelsumme xw.WriteStartElement("TextBlock"); xw.WriteAttributeString("Margin", "0,0,0,5"); xw.WriteAttributeString("Width", (5 + cDoc.ColumnWidths[1]).ToString()); xw.WriteAttributeString("FontSize", "10"); xw.WriteAttributeString("FontFamily", "Arial"); xw.WriteAttributeString("FontWeight", "Bold"); xw.WriteAttributeString("DockPanel.Dock", "Left"); xw.WriteAttributeString("HorizontalAlignment", "Left"); xw.WriteAttributeString("TextAlignment", "Right"); xw.WriteAttributeString("Text", wert.ToString("C")); xw.WriteEndElement(); // <TextBlock> mit der Einzelsumme xw.WriteStartElement("TextBlock"); xw.WriteAttributeString("Margin", Margin2.ToString() + ",0,0,5"); xw.WriteAttributeString("Width", (5 + cDoc.ColumnWidths[LastIndex - 5]).ToString()); xw.WriteAttributeString("FontSize", "10"); xw.WriteAttributeString("FontFamily", "Arial"); xw.WriteAttributeString("FontWeight", "Bold"); xw.WriteAttributeString("DockPanel.Dock", "Left"); xw.WriteAttributeString("HorizontalAlignment", "Left"); xw.WriteAttributeString("TextAlignment", "Right"); xw.WriteAttributeString("Text", wert7.ToString("C")); xw.WriteEndElement(); // <TextBlock> mit der Einzelsumme xw.WriteStartElement("TextBlock"); xw.WriteAttributeString("Margin", "0,0,0,5"); xw.WriteAttributeString("Width", (5 + cDoc.ColumnWidths[LastIndex - 4]).ToString()); xw.WriteAttributeString("FontSize", "10"); xw.WriteAttributeString("FontFamily", "Arial"); xw.WriteAttributeString("FontWeight", "Bold"); xw.WriteAttributeString("DockPanel.Dock", "Left"); xw.WriteAttributeString("HorizontalAlignment", "Left"); xw.WriteAttributeString("TextAlignment", "Right"); xw.WriteAttributeString("Text", skNetto.ToString("C")); xw.WriteEndElement(); // <TextBlock> mit der Einzelsumme xw.WriteStartElement("TextBlock"); xw.WriteAttributeString("Margin", "0,0,0,5"); xw.WriteAttributeString("Width", (5 + cDoc.ColumnWidths[LastIndex - 3]).ToString()); xw.WriteAttributeString("FontSize", "10"); xw.WriteAttributeString("FontFamily", "Arial"); xw.WriteAttributeString("FontWeight", "Bold"); xw.WriteAttributeString("DockPanel.Dock", "Left"); xw.WriteAttributeString("HorizontalAlignment", "Left"); xw.WriteAttributeString("TextAlignment", "Right"); xw.WriteAttributeString("Text", sk7.ToString("C")); xw.WriteEndElement(); // <TextBlock> mit der Einzelsumme xw.WriteStartElement("TextBlock"); xw.WriteAttributeString("Margin", "0,0,0,5"); xw.WriteAttributeString("Width", (5 + cDoc.ColumnWidths[LastIndex - 2]).ToString()); xw.WriteAttributeString("FontSize", "10"); xw.WriteAttributeString("FontFamily", "Arial"); xw.WriteAttributeString("FontWeight", "Bold"); xw.WriteAttributeString("DockPanel.Dock", "Left"); xw.WriteAttributeString("HorizontalAlignment", "Left"); xw.WriteAttributeString("TextAlignment", "Right"); xw.WriteAttributeString("Text", sk19.ToString("C")); xw.WriteEndElement(); // <TextBlock> mit der Einzelsumme xw.WriteStartElement("TextBlock"); xw.WriteAttributeString("Margin", "0,0,0,5"); xw.WriteAttributeString("Width", (5 + cDoc.ColumnWidths[LastIndex - 1]).ToString()); xw.WriteAttributeString("FontSize", "10"); xw.WriteAttributeString("FontFamily", "Arial"); xw.WriteAttributeString("FontWeight", "Bold"); xw.WriteAttributeString("DockPanel.Dock", "Left"); xw.WriteAttributeString("HorizontalAlignment", "Left"); xw.WriteAttributeString("TextAlignment", "Right"); xw.WriteAttributeString("Text", bezahlt.ToString("C")); xw.WriteEndElement(); // </DockPanel> xw.WriteEndElement(); // </DockPanel> xw.WriteEndElement(); // </BlockUIContainer> xw.WriteEndElement(); } /// <summary> /// Erstellt das gewünschte Dokument für den Druck /// </summary> /// <param name="currDoc">das SimFi7-Druckdokument</param> public void GetDocument(SimFi7Document currDoc) { using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) { // Daten DateTime dtTagesSaldo = new DateTime(1980, 1, 31); decimal sumTagesSaldo = 0; decimal sumKomplett = 0; decimal sumSkonto = 0; decimal sumSkonto7 = 0; decimal sumSkontoNetto = 0; decimal sumbetrag7 = 0; int lastKonto = -1; bool first = true; // Xml-Settings XmlWriterSettings xmlSettings = new XmlWriterSettings(); // Xml-Writer erstellen XmlWriter xw = XmlWriter.Create(ms); // Dokument eröffnen xw.WriteStartElement("FlowDocument", "http://schemas.microsoft.com/winfx/2006/xaml/presentation"); xw.WriteAttributeString("xmlns", "x", null, "http://schemas.microsoft.com/winfx/2006/xaml"); // Einstellungen xw.WriteStartElement("Section"); xw.WriteAttributeString("FontSize", "11"); xw.WriteAttributeString("FontFamily", "Arial"); // die Tabelle xw.WriteStartElement("Table"); xw.WriteAttributeString("CellSpacing", "5"); // die Spalten xw.WriteStartElement("Table.Columns"); // Breiten für das jeweilige Dokument setzen currDoc.ColumnWidths.Clear(); if (currDoc.DocumentType == SimFi7Document.DocType.DocBelege) currDoc.ColumnWidths.AddRange(new double[] { 80, 80, 60, 60, 60, 300 }); else currDoc.ColumnWidths.AddRange(new double[] { 200, 70, 60, 60, 60, 70, 70, 70, 70, 70, 150 }); // Berater-Version ? if (App.Current.IstBeraterVersion) currDoc.ColumnWidths.Insert(2, 60); // Spalten schreiben foreach (double ColWidth in currDoc.ColumnWidths) XmlTableColumn(xw, (int)ColWidth); // </Table.Columns> xw.WriteEndElement(); xw.WriteStartElement("TableRowGroup"); xw.WriteAttributeString("FontSize", "11"); // die Daten aufbereiten CollectionViewSource cvs = new CollectionViewSource(); cvs.Source = this; // Sortierung if (currDoc.EnableSortAccounts) { cvs.SortDescriptions.Add(new SortDescription("Konto", ListSortDirection.Ascending)); cvs.SortDescriptions.Add(new SortDescription("Datum", ListSortDirection.Ascending)); } else { cvs.SortDescriptions.Add(new SortDescription("Datum", ListSortDirection.Ascending)); cvs.SortDescriptions.Add(new SortDescription("Konto", ListSortDirection.Ascending)); } // die Daten foreach (Buchung bu in cvs.View) { // richtige Art ? if (currDoc.DocumentType == SimFi7Document.DocType.DocBelege && bu.Typ != Buchung.BuchungsTyp.Beleg) continue; if (currDoc.DocumentType != SimFi7Document.DocType.DocBelege && bu.Typ == Buchung.BuchungsTyp.Beleg) continue; if ((currDoc.DocumentType == SimFi7Document.DocType.DocWarenausgang && bu.Typ != Buchung.BuchungsTyp.Ausgangsrechnung) || (currDoc.DocumentType == SimFi7Document.DocType.DocWareneingang && bu.Typ != Buchung.BuchungsTyp.Eingangsrechnung)) continue; // Konto gewünscht ? if (!currDoc.KontenListe.IsAccountSelected(bu.Konto)) continue; // "Alte" Tabelle abschließen ? if (((currDoc.TagesSaldo && bu.Datum.Day != dtTagesSaldo.Day && currDoc.DocumentType == SimFi7Document.DocType.DocBelege) || (lastKonto != bu.Konto && currDoc.EnableSortAccounts)) && !first) { // abschließen xw.WriteEndElement(); // TableRowGroup xw.WriteEndElement(); // Table xw.WriteEndElement(); // Section // Belege => Gesamtsumme anzeigen if (currDoc.DocumentType == SimFi7Document.DocType.DocBelege) { // Ausgeben XmlWriteSumLine(xw, currDoc.ColumnWidths[0] / 2, 240, sumTagesSaldo, currDoc.TagesSaldo, sumKomplett); // Saldo löschen sumTagesSaldo = 0; } else { // Ausgeben XmlWarenbuchWriteSumLine(xw, currDoc, sumKomplett, sumbetrag7, sumSkontoNetto, sumSkonto, sumSkonto7); // Saldo löschen sumTagesSaldo = 0; sumKomplett = 0; sumSkonto = 0; sumSkonto7 = 0; sumSkontoNetto = 0; sumbetrag7 = 0; } // übernehmen dtTagesSaldo = bu.Datum; // Einstellungen xw.WriteStartElement("Section"); // Seitenwechsel ? if (currDoc.TagesSaldoSinglePage || (lastKonto != bu.Konto && currDoc.EnableSortAccounts)) xw.WriteAttributeString("BreakPageBefore", "true"); xw.WriteAttributeString("FontSize", "11"); xw.WriteAttributeString("FontFamily", "Arial"); // die Tabelle xw.WriteStartElement("Table"); xw.WriteAttributeString("CellSpacing", "5"); // die Spalten xw.WriteStartElement("Table.Columns"); // Spalten schreiben foreach (double ColWidth in currDoc.ColumnWidths) XmlTableColumn(xw, (int)ColWidth); // </Table.Columns> xw.WriteEndElement(); xw.WriteStartElement("TableRowGroup"); xw.WriteAttributeString("FontSize", "11"); // Konto lastKonto = bu.Konto; } // Zeile(n) beginnen xw.WriteStartElement("TableRow"); // Flag löschen if (first) { first = false; lastKonto = bu.Konto; } // aufsummieren sumTagesSaldo += bu.Wert; sumKomplett += bu.Wert; /////////////////////////////////////////////////// // // Inhalt des Dokumentes erstellen // // Welche Art von Dokument ? if (currDoc.DocumentType == SimFi7Document.DocType.DocBelege) { // // -==<< Belege >>==- // // Haben if (bu.Wert >= 0) XmlWriteTableCellContent(xw, bu.Wert.ToString("C"), TextAlignment.Right); else XmlWriteTableCellContent(xw, ""); // Soll if (bu.Wert < 0) XmlWriteTableCellContent(xw, bu.Wert.ToString("C"), TextAlignment.Right, "Red"); else XmlWriteTableCellContent(xw, ""); // Gegenkonto ? if (App.Current.IstBeraterVersion) XmlWriteTableCellContent(xw, bu.Gegenkonto.ToString(), TextAlignment.Right); // Belegnummer XmlWriteTableCellContent(xw, bu.Nummer.ToString(), TextAlignment.Right); // Datum XmlWriteTableCellContent(xw, bu.Datum.ToString("dd.MM.yyyy")); // Konto XmlWriteTableCellContent(xw, bu.Konto.ToString(), TextAlignment.Right); // Text XmlWriteTableCellContent(xw, bu.Zusatztext); } else { // // -==<< Warenbücher >>==- // // Text XmlWriteTableCellContent(xw, bu.Zusatztext); // Wert XmlWriteTableCellContent(xw, bu.Wert.ToString("C"), TextAlignment.Right); // Gegenkonto ? if (App.Current.IstBeraterVersion) XmlWriteTableCellContent(xw, bu.Gegenkonto.ToString(), TextAlignment.Right); // Rechnungs-Nr XmlWriteTableCellContent(xw, bu.Nummer.ToString(), TextAlignment.Right); // Datum XmlWriteTableCellContent(xw, bu.Datum.ToString("dd.MM.yyyy")); // Konto XmlWriteTableCellContent(xw, bu.Konto.ToString(), TextAlignment.Right); // Betrag (7%) XmlWriteTableCellContent(xw, bu.MinderWert.ToString("C"), TextAlignment.Right); // Skonto-Beträge XmlWriteTableCellContent(xw, bu.SkontoNetto.ToString("C"), TextAlignment.Right); XmlWriteTableCellContent(xw, bu.MinderSkonto.ToString("C"), TextAlignment.Right); XmlWriteTableCellContent(xw, bu.Skonto.ToString("C"), TextAlignment.Right); // bezahlt XmlWriteTableCellContent(xw, (bu.Wert - bu.SkontoNetto - bu.MinderSkonto - bu.Skonto).ToString("C"), TextAlignment.Right); // am, durch XmlWriteTableCellContent(xw, bu.Einzahler); // aufaddieren sumSkonto += bu.Skonto; sumSkonto7 += bu.MinderSkonto; sumSkontoNetto += bu.SkontoNetto; sumbetrag7 += bu.MinderWert; } // abschließen xw.WriteEndElement(); } // abschließen xw.WriteEndElement(); // TableRowGroup xw.WriteEndElement(); // Table xw.WriteEndElement(); // Section // Belege => Gesamtsumme anzeigen if (currDoc.DocumentType == SimFi7Document.DocType.DocBelege) { // Ausgeben XmlWriteSumLine(xw, currDoc.ColumnWidths[0] / 2, 240, sumTagesSaldo, currDoc.TagesSaldo, sumKomplett); } else { // Ausgeben XmlWarenbuchWriteSumLine(xw, currDoc, sumKomplett, sumbetrag7, sumSkontoNetto, sumSkonto, sumSkonto7); } // fertig xw.Close(); // zurück an den Start ms.Position = 0; // das FlowDocument zuweisen currDoc.Document = (FlowDocument)XamlReader.Load(ms); } }The result is a FlowDocument you can use fror printing, etc.
You have to replace "Buchung" and all its related lines with the class and values you want to print out.
Greetings,
Chris- Marked As Answer by Annabella LuoModerator Thursday, March 22, 2012 5:56 AM
-
Wednesday, March 14, 2012 12:11 PM
thank-you for Ur support chris,
This is long one but it is very help full. let me try it and send the feed back.
Regards,
sajith
-
Thursday, March 22, 2012 5:56 AMModeratorWe are temporarily marking this as "Answer", if you have any concerns or new findings; please feel free to let me know.
Best regards.Annabella Luo[MSFT]
MSDN Community Support | Feedback to us
-
Friday, March 23, 2012 5:14 AM
Hi EveryBody,
I was bit busy with my work.i temporarily stopped the Report Engine work .
Regards,
sajith

