ActiveReports 18 .NET Edition
Developers / Create Applications / End User Report Designer in WinForms Application / Use End-User Report Designer API / Work with a Report
In This Topic
    Work with a Report
    In This Topic

    The End User Designer API for WinForms allows you to perform common operations with a report using the Designer class.

    Initialize Designer with a new report

    Use Designer.NewReport method to create a new empty report and initialize the Designer as shown in the code example.

    C#. Add using statements on the top of Form.cs
    Copy Code
    using System.Windows.Forms;
    using GrapeCity.ActiveReports.Design;
    
    C# code. Paste INSIDE the Form Load event
    Copy Code
    var _designer = new Designer() { Dock = DockStyle.Fill };
    _designer.NewReport(DesignerReportType.Rdl);
    Controls.Add(_designer);
    

    Note: You should use the Report property only if you want to get the current state information. Please do not use this property if you need to change the report state or assign a new report.

    Initialize Designer with a specified report

    Use the Designer.LoadReport method to initialize the Designer by loading a report created in code, as demonstrated in the code example.

    Copy Code
    var report = new PageReport {
          Report = {
            DataSources = {
                  new DataSource {
                      Name = "MainDataSource",
                      ConnectionProperties = {
                          ConnectString = "<your_connection_string>",
                          DataProvider = "MSSQL",
                      }
                  }
              }
          }
      };
    //Serialize and load report into the designer
    _designer.LoadReport(XmlReader.Create(new StringReader(report.ToRdlString())), DesignerReportType.Rdl);
    

    Save a report

    Save a report to any storage by passing the XmlWriter object to the Designer.SaveReport method. See the example code for details.

    C#. Add using statements on the top of Form.cs
    Copy Code
    using System.IO;
    using System.Xml;
    using GrapeCity.ActiveReports.Design;
    
    C#.
    Copy Code
    private void SaveReport(Stream outStream)
    {
      using(var writer = XmlWriter.Create(outStream))
      {
        _designer.SaveReport(writer);
      }
    }
    

    Define a font resolver

    Using the Designer.FontResolver property, you can provide your own fonts to be used for the report design and preview. For that, you must first define your own font resolver and then attach it to the Designer instance. See the code example for details.

    C#. Add using statements on the top of Form.cs
    Copy Code
    using GrapeCity.ActiveReports;
    using GrapeCity.ActiveReports.Design;
    
    C#. Define a custom font resolver
    Copy Code
    public sealed class DirectoryFontResolver : IFontResolver
    {
        GrapeCity.Documents.Text.FontCollection _fonts;
    
        public DirectoryFontResolver(string fontsDirectory)
        {
            _fonts = new GrapeCity.Documents.Text.FontCollection();
            // load standard Windows fonts
            _fonts.RegisterDirectory(Environment.GetFolderPath(Environment.SpecialFolder.Fonts));
            // load fonts from custom directory
            _fonts.RegisterDirectory(fontsDirectory);
            _fonts.DefaultFont = _fonts.FindFamilyName("Arial");
        }
        GrapeCity.Documents.Text.FontCollection IFontResolver.GetFonts(string familyName, bool isBold, bool isItalic)
        {
            var fonts = new GrapeCity.Documents.Text.FontCollection();
            fonts.Add(_fonts.FindFamilyName(familyName, isBold, isItalic) ?? _fonts.DefaultFont);
            return fonts;
        }
    }
    
    C#. Attach a custom font resolver to the Designer instance
    Copy Code
    class MyDesignerForm : Form
    {
      public MyDesignerForm()
      {
        InitializeComponent();
        //The designer must be added to the form with the name '_designer'.    
        _designer.FontResolver = new DirectoryFontResolver("c:\\Fonts");
      }
    }
    

    Specify a custom resource locator

    Using the Designer.ResourceLocator property, you can define a custom resource locator to get the resources (like images, subreports) from the custom storage or at a specific disk location. First, define the custom resource locator and then use it in the Designer. See the code example for details.

    C#. Add using statements on the top of Form.cs
    Copy Code
    using System;
    using System.IO;
    using System.Drawing;
    using GrapeCity.ActiveReports;
    
    C#. Define a custom resource locator
    Copy Code
    class MyResourceLocator : ResourceLocator
    {
        public override Resource GetResource(ResourceInfo resourceInfo)
        {
            if (resourceInfo.Name == "redSquare.png")
            {
                //Here we draw the image with the red square in the center.
                //You can load the image from file system, or from data base, or from assembly resources.
                var img = new Bitmap(100, 100);
                var graphics = Graphics.FromImage(img);
                var redBrush = new SolidBrush(Color.Red);
                graphics.FillRectangle(redBrush, 10, 10, 80, 80);
                var tmpStream = new MemoryStream();
                img.Save(tmpStream, System.Drawing.Imaging.ImageFormat.Png);
                tmpStream.Position = 0;
                return new Resource(tmpStream, new Uri("redSquare.png", UriKind.Relative));
            }
            return new Resource();
        }
    }
    
    C#. Attach a custom resource locator to the Designer instance
    Copy Code
    class MyDesignerForm : Form
    {
      public MyDesignerForm()
      {
        InitializeComponent();
        //The designer must be added to the form with the name '_designer'.   
        _designer.ResourceLocator = new MyResourceLocator();
      }
    

    Execute specific Designer actions

    With the Designer.ExecuteAction(DesignerAction) method, you can execute some specified designer action. Most Designer APIs related to reports are encapsulated into the ExecuteAction method. The code example below demonstrates how you can remove all selected items.

    C#
    Copy Code
    private void RemoveSelectedItems()
    {
      _designer.ExecuteAction(DesignerAction.EditDelete);
    }
    

    The code example below demonstrates how you can select all items and remove them.

    C#
    Copy Code
    private void Clear()
    {
      _designer.ExecuteAction(DesignerAction.SelectAll);
      _designer.ExecuteAction(DesignerAction.EditDelete);
    }
    

    Supply credentials for a data provider

    Use the Designer.LocateCredentials event to provide credentials for data providers as demonstrated in the code example.

    C#. Add using statements on the top of Form.cs
    Copy Code
    using System.Windows.Forms;
    using GrapeCity.ActiveReports;
    using GrapeCity.ActiveReports.Design;
    
    C#
    Copy Code
    _designer.LocateCredentials += (sender, args) => {
      args.UserName = "sa";
      args.Password = "12345";
    }
    

    Provide data for a page report

    Use the Designer.LocateDataSource event to provide data for previewing a page report as demonstrated in the code example.

    C#
    Copy Code
    _designer.LocateDataSource += (sender, args) => {
      var dataSourceName = args.DataSet.Query.DataSourceName;
      var dataSource = ((PageReport)designer.Report).Report.DataSources.First(x => x.Name == dataSourceName);
      if(dataSource.ConnectionProperties.DataProvider == "OBJECT")
      {
        args.Data = new[] { new { CustomerName = "Gc Inc." } };
      }
    };
    

    Get the selected items collection

    Use the Designer.Selection property or the Designer.SelectionChanged event to react to selection changes. Using the Designer.Selection property, you can get the selected items collection. The code example below demonstrates changing the 'remove' button state, which must be enabled only when there are selected items.

    C#
    Copy Code
    _designer.SelectionChanged += () {
      removeButton.Enabled =
        _designer.Selection.OfType<ReportItem>().Count() > 0
        || designer.Selection.OfType<ARControl>().Count() > 0;
    }
    

    Get the changed undo history

    The UndoManager.Changed event occurs when the report was changed and therefore the undo history was changed as well. You can use this event in the conjunction with the UndoManager.UndoCount and UndoManager.RedoCount properties to set the Undo/Redo buttons state as shown in the code example.

    C#
    Copy Code
    _designer.UndoManager.Changed += (sender, e) => {
      _undoButton.Enabled = _designer.UndoManager.UndoCount > 0;
      _redoButton.Enabled = _designer.UndoManager.RedoCount > 0;
    };
    

    Handle actions after changing the report layout

    With the Designer.LayoutChanged event, you can execute some actions right after the layout has been changed as in the code example below.

    C#
    Copy Code
    _designer.LayoutChanged += (sender, args) => {
      //do some work here
    };
    

    Handle report layout changes

    The Designer.LayoutChanging event allows to handle the report layout changes. The example below deprecates adding a new control without a dataset.

    C#
    Copy Code
    _designer.LayoutChanging += (sender, args) => {
          if (args.Type == LayoutChangeType.ControlAdd
          && designer.Report is PageReport pageReport
          && pageReport.Report.DataSets.Count == 0)
          {
            ((IUIService)designer).ShowError("Add data set first.");
            args.AllowChange = false;
          }
      };
    

    Check if a Designer action is enabled

    With the Designer.QueryActionEnabled(DesignerAction) method, you can check if a specific action in the Designer is enabled.

    C#
    Copy Code
    var canConvert = designer.QueryActionEnabled(DesignerAction.ConvertToMaster);
    //canConvert value will be 'false' for master reports and 'true' for rdl reports.
    

    Return a currently opened report

    The Designer.Report property returns a currently opened report, which can be a Page report or a Section report.

    To set a report, you should use the Designer.LoadReport method.
    C#
    Copy Code
    var extension = switch designer.Report {
      PageReport => ".rdlx",
      SectionReport => ".rpx",
      _ => throw new Exception("Unknown report type.")
    };
    

    Update some button states after the report changes

    The Designer.ReportChanged event occurs when any change to a report has been applied (layout changes or data layer changes). You can use this event to update some button states as in the example below.

    C#
    Copy Code
    _designer.ReportChanged += (sender, args) => {
      saveButton.Enabled = true;
    };
    

    Show the Data Source creation wizard

    The Designer.RunDataWizard event opens the data source creation wizard.

    C#
    Copy Code
    private void RunDataWizardButtonClick(object sender, EventArgs e)
    {
        _designer.RunDataWizard();
    }