Einschränkungen von RDL
Ich habe ursprünglich RDLC / ReportViewer zum Drucken mit WPF verwendet, fand es aber sehr einschränkend. Einige der Einschränkungen, die ich gefunden habe, waren:
- RDL konnte nur die langweiligsten Berichte erstellen
- Das Erstellen eines Berichts mit RDL war viel aufwändiger als mit direktem WPF: Die Entwurfswerkzeuge sind im Vergleich zu Expression Blend- und RDL-Deals nur in Tabellen sehr primitiv
- Ich konnte ControlTemplates, DataTemplates, Styles usw. Nicht verwenden
- Meine Berichtsfelder und -spalten konnten aufgrund der Datengröße nicht effektiv in der Größe geändert und neu angeordnet werden
- Grafiken mussten als Bilder importiert werden - sie konnten nicht als Vektoren gezeichnet oder bearbeitet werden
- Die Positionierung von Elementen erforderte eher Code-Behind als Datenbindung
- Fehlende Transformationen
- Sehr primitive Datenbindung
Das Drucken direkt aus WPF ist sehr einfach
Aufgrund dieser Einschränkungen habe ich mich mit der Erstellung von Berichten mit reinem WPF befasst und festgestellt, dass dies wirklich ziemlich trivial ist. Mit WPF können Sie Ihre eigene DocumentPaginator
Unterklasse implementieren , die Seiten generieren kann.
Ich habe eine einfache DocumentPaginator-Unterklasse entwickelt, die alle visuellen Elemente verwendet, den visuellen Baum analysiert und ausgewählte Elemente ausblendet, um jede Seite zu erstellen.
DocumentPaginator-Details
Folgendes bewirkt meine DocumentPaginator-Unterklasse während der Initialisierung (aufgerufen beim Abrufen des ersten PageCount oder beim ersten Aufruf von GetPage ()):
- Scannt den visuellen Baum und erstellt eine Karte aller gescrollten Bedienfelder in ItemsControls
- Beginnend mit dem äußersten Punkt werden Elemente in den ItemsControls von vornherein unsichtbar, bis das Visual auf eine einzelne Seite passt, ohne dass ein Bildlauf erforderlich ist. Wenn die äußerste nicht genug reduziert werden kann, werden die Innenverkleidungen reduziert, bis sie erfolgreich sind oder nur noch ein Gegenstand auf jeder Ebene vorhanden ist. Notieren Sie den Satz sichtbarer Elemente als erste Seite.
- Blenden Sie die Elemente der untersten Ebene aus, die bereits auf der ersten Seite angezeigt wurden, und machen Sie nachfolgende Elemente sichtbar, bis sie nicht mehr auf die Seite passen. Notieren Sie alle Elemente außer dem zuletzt hinzugefügten als zweite Seite.
- Wiederholen Sie den Vorgang für alle Seiten und speichern Sie die Ergebnisse in einer Datenstruktur.
Die GetPage-Methode meines DocumentPaginator lautet wie folgt:
- Suchen Sie die angegebene Seitenzahl in der Datenstruktur, die während der Initialisierung generiert wurde
- Ausblenden und Anzeigen von Elementen im visuellen Baum, wie in der Datenstruktur angegeben
- Legen Sie die angehängten Eigenschaften PageNumber und NumberOfPages fest, damit der Bericht die Seitennummerierung anzeigen kann
- Leeren Sie den Dispatcher (
Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => {} ));
), um alle Aufgaben zum Rendern des Hintergrunds abzuschließen
- Erstellen Sie ein Rechteck in der Größe der Seite, deren VisualBrush das zu druckende Bild ist
- Messen, Anordnen und Aktualisieren Legen Sie das Rechteck fest und geben Sie es zurück
Dies stellte sich als recht einfacher Code heraus und ermöglichte es mir, praktisch alles, was ich mit WPF erstellen konnte, in Seiten umzuwandeln und auszudrucken.
Zusätzliche Berichtsunterstützung
Jetzt, da mein Paginator funktioniert, muss ich mir keine Sorgen mehr machen, ob ich meine WPF-Inhalte für Bildschirm oder Papier erstelle. Tatsächlich funktioniert die Benutzeroberfläche, die ich für die Dateneingabe und -bearbeitung erstelle, häufig auch sehr gut zum Drucken.
Von dort aus fügte ich eine einfache Symbolleiste und etwas Code hinzu, was zu einem vollwertigen Berichtssystem führte, das auf WPF basiert und weitaus leistungsfähiger als RDL ist. Mein Berichtscode kann in Dateien exportiert, auf dem Drucker gedruckt, Seitenbilder ausgeschnitten / eingefügt und Daten für Excel ausgeschnitten / eingefügt werden. Ich kann auch jede meiner Benutzeroberflächen mit einem Klick auf ein Kontrollkästchen auf "Druckansicht" umschalten, um zu sehen, wie sie beim Drucken aussehen wird. All dies in nur wenigen hundert Zeilen C # und XAML!
An diesem Punkt denke ich, dass die einzige Funktion, die RDL nicht in meinem Berichtscode hat, die Möglichkeit ist, eine formatierte Excel-Tabelle zu generieren. Ich kann sehen, wie dies getan werden kann, aber bisher war dies nicht erforderlich - das Ausschneiden und Einfügen der Daten allein hat ausgereicht.
Aus meiner Erfahrung heraus würde ich empfehlen, einen Paginator zu schreiben und dann WPF selbst zu verwenden, um Ihre Berichte zu erstellen.