DevExpress Report
De Banane Atomic
(Redirigé depuis Devexpress report)
Aller à la navigationAller à la recherche
Liens utiles
- How to: Customize Dock Panels of the End-User Designer
- How to: Create a Table Report
- Calculated Fields
- Providing Data to Reports
- How to: Customize Dock Panels of the End-User Designer
- Sum
Généré un PDF depuis un template (*.repx)
XtraReport reportDevExpress = XtraReport.FromFile(@"C:\Template.repx", true); // it has to be an ArrayList, otherwise the report is not well filled reportDevExpress.DataSource = new ArrayList(MyDataList); reportDevExpress.ExportToPdf(@"C:\File.pdf"); |
XtraReport Class
|
PDF/A
// PDF/A-2b PdfExportOptions options = new PdfExportOptions() { PdfACompatible = true }; reportDevExpress.ExportToPdf(@"C:\File.pdf", options); // PDF/A-3b string additionalMetadata = File.ReadAllText("DocumentInfo.txt") + File.ReadAllText("PdfASchema.txt"); PdfExportOptions options = new PdfExportOptions() { PdfACompatible = true, AdditionalMetadata = additionalMetadata, }; reportDevExpress.ExportToPdf(@"C:\File.pdf", options); |
PDF/A-3b | v 14.2.6 |
PDF/A-2b | v 14.1.3 |
PdfExportOptions Class
|
Designer WinForm dans une fenêtre WPF
<Window xmlns:userDesigner="clr-namespace:DevExpress.XtraReports.UserDesigner;assembly=DevExpress.XtraReports.v13.2.Extensions" xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"> <Grid> <WindowsFormsHost> <WindowsFormsHost.Child> <wf:UserControl x:Name="ucDockingWindows"> <wf:UserControl.Controls> <userDesigner:XRDesignPanel x:Name="panel" Dock="Fill" /> </wf:UserControl.Controls> </wf:UserControl> </WindowsFormsHost.Child> </WindowsFormsHost> </Grid> </Window> |
public MainWindow() { InitializeComponent(); var dockManager = new XRDesignDockManager(); dockManager.Form = ucDockingWindows; dockManager.Initialize(panel, DesignDockPanelType.All); var barManager = new XRDesignBarManager(); barManager.Form = ucDockingWindows; barManager.Initialize(panel); barManager.DockManager = dockManager; // Remove tool bar stuff panel.SetCommandVisibility(ReportCommand.AddNewDataSource, CommandVisibility.None); // Close GroupAndSort DesignDockPanel var designDockPanel = (GroupAndSortDockPanel)dockManager[DesignDockPanelType.GroupAndSort]; designDockPanel.Close(); // get a specific DesignDockPanel from its name var designDockPanel = dockManager.Panels.OfType<TypedDesignDockPanel>().FirstOrDefault(p => p.GetType().Name.StartsWith(DesignDockPanelType.GroupAndSort.ToString())); // set report datasource report.DataSource = dataSource; |
Afficher une preview
var report = XtraReport.FromFile(@"Chemin\vers\le\fichier.repx", true); using (ReportPrintTool printTool = new ReportPrintTool(report)) { printTool.ShowPreviewDialog(); } |
Éditer avec le designer classique
var report = XtraReport.FromFile(@"Chemin\vers\le\fichier.repx", true); using (ReportPrintTool printTool = new ReportPrintTool(report)) { printTool.ShowDesignerDialog(); } |
Masquer des boutons dans le ruban
reportDesigner1.SetCommandVisibility(ReportCommand.SaveAll, CommandVisibility.None); |
Rafraichir le nom du rapport dans un onglet
XRDesignMdiController _controller; var host = (IDesignerHost)_controller.ActiveDesignPanel.GetService(typeof(IDesignerHost)); var changeSrv = (IComponentChangeService)host.GetService(typeof(IComponentChangeService)); changeSrv.OnComponentChanging(_controller.ActiveDesignPanel.Report, null); _controller.ActiveDesignPanel.Report.DisplayName = "Nouveau nom de rapport"; changeSrv.OnComponentChanged(_controller.ActiveDesignPanel.Report, null, null, null); |
- BarButtonItem.ActAsDropDown Property
- BarButtonItem.DropDownControl Property
- DevExpress.XtraReports.UserDesigner Namespace
Override Commands in the End-User Designer (Custom Saving)
New
public ReportsDesigner() { reportDesigner1.AddCommandHandler(new MainCommandHandler(reportDesigner1); /* ** */ public class MainCommandHandler : ICommandHandler { private XRDesignMdiController _controller; public bool CanHandleCommand(ReportCommand command, ref bool useNextHandler) { useNextHandler = command != ReportCommand.NewReport; return !useNextHandler; } public void HandleCommand(ReportCommand command, object[] args) { _controller.CreateNewReport(); _controller.ActiveDesignPanel.Report.DataSource = ...; // Update the Field List var host = (IDesignerHost)_controller.ActiveDesignPanel.GetService(typeof(IDesignerHost)); _fieldList.UpdateDataSource(host); // Change the DisplayName var changeSrv = (IComponentChangeService)host.GetService(typeof(IComponentChangeService)); changeSrv.OnComponentChanging(_controller.ActiveDesignPanel.Report, null); _controller.ActiveDesignPanel.Report.DisplayName = ...; changeSrv.OnComponentChanged(_controller.ActiveDesignPanel.Report, null, null, null); // Change the FileName _controller.ActiveDesignPanel.FileName = ...; // display a star at the right of the name in the tab to inform that the file is not saved yet _controller.ActiveDesignPanel.ReportState = ReportState.Changed; |
Save
private void reportDesigner1_DesignPanelLoaded(object sender, DesignerLoadedEventArgs e) { XRDesignPanel panel = (XRDesignPanel)sender; reportDesigner1.AddCommandHandler(new SaveCommandHandler(reportDesigner1, panel)); /* ** */ public class SaveCommandHandler : ICommandHandler { private XRDesignMdiController _controller; private XRDesignPanel _panel; public bool CanHandleCommand(ReportCommand command, ref bool useNextHandler) { // ici on choisit les commandes qui seront gérées useNextHandler = command != ReportCommand.SaveFile && command != ReportCommand.SaveFileAs && command != ReportCommand.Closing; return !useNextHandler; } public void HandleCommand(ReportCommand command, object[] args) { switch (command) { case ReportCommand.SaveFile: HandleSave(); break; case ReportCommand.SaveFileAs: HandleSaveAs(); break; case ReportCommand.Closing: HandleClosing(args); break; default: break; } } private void HandleSave() { if (File.Exists(_panel.FileName)) { // Save template _panel.Report.SaveLayout(_panel.FileName, true); // Prevent the "Report has been changed" dialog from being shown. _panel.ReportState = ReportState.Saved; } else { HandleSaveAs(); } } private void HandleClosing(object[] args) { if (_panel.ReportState == ReportState.Changed) { if (args.Length == 2) { var panelForm = args[0] as XRDesignPanelForm; var cancelEventArgs = args[1] as CancelEventArgs; if (panelForm != null && cancelEventArgs != null) { // Select the report in the tabs _panel.Select(); MessageBoxResult messageBoxResult = MessageBox.Show( String.Format("The template '{0}' has changed. Do you want to save it?", panelForm.ReportDisplayName), "Template has changed", MessageBoxButton.YesNoCancel); if (messageBoxResult == MessageBoxResult.Cancel) { cancelEventArgs.Cancel = true; } } } } } } |
Field List
Provide Custom Names for Data Items in the Field List
DataSource: Wrapper dynamique
Pour chaque élément de DataList, on créé un wrapper: pour chaque propriété marquée de l'attribut [Field("Nom affiché", "Groupe")]
- on créé un groupe s'il n'existe pas déjà
- où on y ajoute une propriété "Nom affiché"
- avec la valeur de la propriété.
XtraReport reportDevExpress = XtraReport.FromFile(templateFilePath, true); reportDevExpress.DataSource = GetDataSource(); public object GetDataSource() { var wrapperArrayList = new DataWrapperArrayList("Nom de la Field List"); // wrap chaque élément de DataList foreach (var wrapper in DataList.Select(r => DataWrapperForDesigner<FieldAttribute>.BuildDynamicWrapper(r, true))) { wrapperArrayList.Add(wrapper); } return wrapperArrayList; } // pour le Designer on n'a besoin juste d'un élément (data) et pas de la liste de tous les éléments (DataList) // on a besoin de la structure de l'élément (liste des propriétés mais pas des valeurs) public object GetDataSourceSkeleton() { var dynamicWrapper = DataWrapperForDesigner<FieldAttribute>.BuildDynamicWrapper(data, false); var dynamicWrapperArrayList = new DataWrapperArrayList("Nom de la Field List") { dynamicWrapper }; dynamicWrapperArrayList.DisplayNames = DataWrapperForDesigner<FieldAttribute>.DisplayNames; return dynamicWrapperArrayList; } |
public class DataWrapperArrayList : ArrayList, IDisplayNameProvider { private string _dataSourceDisplayName; public DataWrapperArrayList(string dataSourceDisplayName) { _dataSourceDisplayName = dataSourceDisplayName; } public string GetDataSourceDisplayName() { return _dataSourceDisplayName; } public string GetFieldDisplayName(string[] fieldAccessors) { var fieldName = fieldAccessors[fieldAccessors.Length - 1]; if (DisplayNames != null && DisplayNames.ContainsKey(fieldName)) { return DisplayNames[fieldName]; } else { // Inserts spaces in the field names. return SpaceFieldNames(fieldName); } } private string SpaceFieldNames(string fieldName) { string result = string.Empty; bool isPrevLow = false; foreach (char symb in fieldName) { // Check if a character is of upper case. // To avoid spaces inside abbreviations, // check if the previous character is of upper case, too. if (Char.IsUpper(symb) && isPrevLow) { result += " " + symb; } else { result += symb; } isPrevLow = Char.IsLower(symb); } return result; } public IDictionary<string, string> DisplayNames { get; set; } } |
public class DataWrapperForDesigner<A> where A : Attribute, IFieldAttribute { /// <summary> /// Store the dynamic wrapper type after it has been build the first time. /// This to avoid creating a different type each type. /// </summary> private static IDictionary<Type, Type> _dynamicWrapperTypes; /// <summary> /// Builds the type of the dynamic wrapper or get the previously built type. /// </summary> /// <returns></returns> private static Type BuildDynamicWrapperType(Type reportType) { // create once the dynamicWrapperType for a report type if (!_dynamicWrapperTypes.ContainsKey(reportType)) { ModuleBuilder moduleBuilder; TypeBuilder typeBuilder = CreateTypeBuilder("DynamicWrapper", "DynamicWrapper.dll", "DynamicWrapper", out moduleBuilder); var propertiesGroups = new Dictionary<string, List<PropertyInfo>>(); // for each properties with the attribute Field foreach (var propertyInfo in reportType.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => Attribute.IsDefined(p, typeof(A)))) { var fieldAttribute = (A)Attribute.GetCustomAttribute(propertyInfo, typeof(A), false); if (!propertiesGroups.ContainsKey(fieldAttribute.Group)) { propertiesGroups[fieldAttribute.Group] = new List<PropertyInfo>(); } propertiesGroups[fieldAttribute.Group].Add(propertyInfo); DisplayNames[propertyInfo.Name] = fieldAttribute.DisplayName; } // for each group create a dynamic class foreach (var group in propertiesGroups.Keys) { TypeBuilder groupTypeBuilder = CreateTypeBuilder(group, moduleBuilder); foreach (var propertyInfo in propertiesGroups[group]) { AddProperty(groupTypeBuilder, propertyInfo.Name, propertyInfo.PropertyType); } Type groupType = groupTypeBuilder.CreateType(); // add the new type as property into the DynamicWrapper AddProperty(typeBuilder, group, groupType); } _dynamicWrapperTypes[reportType] = typeBuilder.CreateType(); } return _dynamicWrapperTypes[reportType]; } /// <summary> /// A dictionary which keys are property names and values names to display in the DevExpress designer. /// </summary> public static IDictionary<string, string> DisplayNames { get; private set; } static DataWrapperForDesigner() { _dynamicWrapperTypes = new Dictionary<Type, Type>(); DisplayNames = new Dictionary<string, string>(); } /// <summary> /// Create the dynamic wrapper object and fill it if needed. /// </summary> public static object BuildDynamicWrapper(object data, bool fillTheWrapperWithData) { var dynamicWrapperType = BuildDynamicWrapperType(data.GetType()); var dynamicWrapper = Activator.CreateInstance(dynamicWrapperType); if (fillTheWrapperWithTheReportData) { var propertiesGroups = new Dictionary<string, List<PropertyNameAndValue>>(); // for each properties of data with the attribute Field foreach (var propertyInfo in report.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => Attribute.IsDefined(p, typeof(A)))) { var fieldAttribute = (A)Attribute.GetCustomAttribute(propertyInfo, typeof(A), false); if (!propertiesGroups.ContainsKey(fieldAttribute.Group)) { propertiesGroups[fieldAttribute.Group] = new List<PropertyNameAndValue>(); } propertiesGroups[fieldAttribute.Group].Add(new PropertyNameAndValue() { PropertyName = propertyInfo.Name, PropertyValue = propertyInfo.GetValue(report, null) }); } foreach (var group in propertiesGroups.Keys) { var groupProperty = dynamicWrapperType.GetProperty(group); var groupInstance = Activator.CreateInstance(groupProperty.PropertyType); foreach (PropertyNameAndValue propertyNameAndValue in propertiesGroups[group]) { if (propertyNameAndValue.PropertyValue != null) { var wrapperProperty = groupProperty.PropertyType.GetProperty(propertyNameAndValue.PropertyName); if (wrapperProperty != null) { wrapperProperty.SetValue(groupInstance, propertyNameAndValue.PropertyValue, null); } else { log.ErrorFormat("Unable to retrieve the property {0} in the class {1}.", propertyNameAndValue.PropertyName, report.GetType().Name); } } } groupProperty.SetValue(dynamicWrapper, groupInstance, null); } } return dynamicWrapper; } /// <summary> /// Creates an assembly, a module and a type builder. /// </summary> /// <param name="assemblyName">Name of the assembly.</param> /// <param name="moduleName">Name of the module.</param> /// <param name="typeName">Name of the type.</param> /// <param name="moduleBuilder">The module builder.</param> /// <returns></returns> private static TypeBuilder CreateTypeBuilder(string assemblyName, string moduleName, string typeName, out ModuleBuilder moduleBuilder) { var assemblyNameObject = new AssemblyName() { Name = assemblyName }; AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyNameObject, AssemblyBuilderAccess.Run); moduleBuilder = assemblyBuilder.DefineDynamicModule(moduleName); return moduleBuilder.DefineType(typeName, TypeAttributes.Public | TypeAttributes.Class); } /// <summary> /// Creates a type builder from a module. /// </summary> /// <param name="typeName">Name of the type.</param> /// <param name="moduleBuilder">The module builder.</param> /// <returns></returns> private static TypeBuilder CreateTypeBuilder(string typeName, ModuleBuilder moduleBuilder) { return moduleBuilder.DefineType(typeName, TypeAttributes.Public | TypeAttributes.Class); } /// <summary> /// Adds the property to the class. /// </summary> /// <param name="typeBuilder">The type builder.</param> /// <param name="propertyName">Name of the property.</param> /// <param name="propertyType">Type of the property.</param> private static void AddProperty(TypeBuilder typeBuilder, string propertyName, Type propertyType) { FieldBuilder fieldBuilder = typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private); PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null); MethodBuilder getPropMthdBldr = typeBuilder.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes); ILGenerator getIl = getPropMthdBldr.GetILGenerator(); getIl.Emit(OpCodes.Ldarg_0); getIl.Emit(OpCodes.Ldfld, fieldBuilder); getIl.Emit(OpCodes.Ret); MethodBuilder setPropMthdBldr = typeBuilder.DefineMethod("set_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new[] { propertyType }); ILGenerator setIl = setPropMthdBldr.GetILGenerator(); Label modifyProperty = setIl.DefineLabel(); Label exitSet = setIl.DefineLabel(); setIl.MarkLabel(modifyProperty); setIl.Emit(OpCodes.Ldarg_0); setIl.Emit(OpCodes.Ldarg_1); setIl.Emit(OpCodes.Stfld, fieldBuilder); setIl.Emit(OpCodes.Nop); setIl.MarkLabel(exitSet); setIl.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getPropMthdBldr); propertyBuilder.SetSetMethod(setPropMthdBldr); } } /// <summary> /// A class used to store the property name with its value. /// </summary> class PropertyNameAndValue { public string PropertyName { get; set; } public object PropertyValue { get; set; } } public interface IFieldAttribute { string DisplayName { get; } string Group { get; } } |