Les limites de la RDL
J'y suis allé avec RDLC/ReportViewer pour l'impression avec WPF, mais il lui est très limitant. Certaines des limites que j'ai trouvées étaient:
- RDL ne peut créer que le plus ennuyeux de rapports
- Il était beaucoup plus de travail pour créer un rapport en utilisant RDL que dans droit en WPF: Les outils de conception sont très primitives par rapport à Expression Blend et de la RDL ne traite que des tableaux
- Je n'ai pas eu la possibilité d'utiliser ControlTemplates, DataTemplates, Styles, etc
- Mon champs de rapport et les colonnes ne pouvaient effectivement redimensionner et réorganiser selon la taille des données
- Les graphismes ont dû être importés que des images - il n'a pas pu être établis ou modifiés en tant que vecteurs
- Le positionnement des éléments requis code-behind plutôt que de la liaison de données
- Manque de transformations
- Très primitive de la liaison de données
Impression directement à partir de WPF est très facile
En raison de ces limitations, j'ai regardé dans la création de rapports à l'aide de pure WPF et a découvert qu'il était vraiment tout à fait banale. WPF permet de mettre en oeuvre votre propre DocumentPaginator
sous-classe qui peuvent générer des pages.
J'ai développé un simple DocumentPaginator sous-classe qui prend tout Visuel, analyse visuelle de l'arbre, et masque les éléments sélectionnés à la création de chaque page.
DocumentPaginator de détails
Voici ce que ma DocumentPaginator sous-classe ne lors de l'initialisation (appelée lors de la première propriété pagecount est rapportée, ou lors de la première GetPage ()):
- Des Scans de l'arbre visuel et rend une carte de tous défiler les panneaux à l'intérieur de ItemsControls
- En commençant par l'extérieur, rend éléments dans le ItemsControls invisible de la dernière à la première jusqu'à ce que le Visuel tient sur une seule page, sans avoir à faire défiler. Si l'extérieur ne peut pas être assez réduit, réduit les panneaux intérieurs jusqu'à ce qu'il réussisse ou n'a qu'un seul élément à chaque niveau. Enregistrement de l'ensemble des éléments visibles que la première page.
- Cacher le plus bas niveau, les éléments qui ont déjà été indiqué sur la première page, puis effectuer par la suite des éléments visibles jusqu'à ce qu'ils ne peuvent plus tenir sur la page. Enregistrement de tous, mais le dernier élément ajouté à la deuxième page.
- Répétez le processus pour toutes les pages, en stockant le résultat dans une structure de données.
Mon DocumentPaginator de GetPage méthode est comme suit:
- Rechercher le numéro de page dans la structure de données générées lors de l'initialisation
- Masquer et afficher des éléments dans l'arborescence visuelle, comme indiqué dans la structure de données
- Ensemble PageNumber et NumberOfPages attaché propriétés, ce rapport peut afficher les numéros de page
- Rincer le Répartiteur (
Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => {} ));
) pour obtenir de rendu en arrière-plan des tâches à remplir
- Créer un Rectangle de la taille de la page dont VisualBrush est le visuel imprimé
- Mesure, d'Organiser et d'UpdateLayout le rectangle, puis le retourner
Ceci s'est avéré être tout à fait simple code, et m'a permis de transformer pratiquement tout ce que j'ai pu créer avec WPF en pages et impression.
Des rapports supplémentaires de soutien
Maintenant que mon paginator est au travail, je n'ai plus à vous inquiéter beaucoup de savoir si je suis la création de mon WPF contenu de l'écran ou sur papier. En fait, souvent de l'INTERFACE utilisateur que je construis pour la saisie des données et l'édition fonctionne aussi très bien pour l'impression.
À partir de là, j'ai ajouté une simple barre d'outils et un peu de code derrière, résultant en un véritable système de déclaration construit autour de WPF qui était beaucoup plus performant que RDL. Mon code de signalement peut exporter des fichiers, d'impression à l'imprimante, copier/coller des images de page, et couper/coller des données pour Excel. Je peux aussi passer tout de mon INTERFACE utilisateur pour l'impression d'une vue" avec un clic sur une case à cocher pour voir ce qu'il va ressembler si elles sont imprimées. Tout cela, en quelques centaines de lignes de C# et XAML!
À ce stade, je pense que la seule fonction de RDL a que mon code de signalement ne pas avoir est la capacité à générer de la mise en forme de feuille de calcul Excel. Je peux voir comment cela pourrait être fait, mais jusqu'à présent il n'y a pas besoin de couper et coller les données a été suffisant.
De mon expérience, ma recommandation serait d'écrire un paginator, puis commencer à utiliser WPF pour créer vos rapports.