# Work with a Report

This topic describes the End-User Report Designer API that concerns working with reports.

## Content



The End User Designer API for WinForms allows you to perform common operations with a report using the [Designer](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.Designer.html) class.

### Initialize Designer with a new report

Use [Designer.NewReport](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.Designer.html) method to create a new empty report and initialize the Designer as shown in the code example.

```csharp.
using System.Windows.Forms;
using GrapeCity.ActiveReports.Design;
```

```csharp
var _designer = new Designer() { Dock = DockStyle.Fill };
_designer.NewReport(DesignerReportType.RdlMultiSection);
Controls.Add(_designer);
```


> type=note
> **Note**: You should use the [Report](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.Designer.html) 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](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.Designer.html) method to initialize the Designer by loading a report created in code, as demonstrated in the code example.

```
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](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.Designer.html) method. See the example code for details.

```csharp.
using System.IO;
using System.Xml;
using GrapeCity.ActiveReports.Design;
```

```csharp.
private void SaveReport(Stream outStream)
{
  using(var writer = XmlWriter.Create(outStream))
  {
    _designer.SaveReport(writer);
  }
}
```

### Define a font resolver

Using the [Designer.FontResolver](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.Designer.html) 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.

```csharp.
using GrapeCity.ActiveReports;
using GrapeCity.ActiveReports.Design;
```

```csharp.
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;
    }
}
```

```csharp.
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](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.Designer.html) 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.

```csharp.
using System;
using System.IO;
using System.Drawing;
using GrapeCity.ActiveReports;
```

```csharp.
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();
    }
}
```

```csharp.
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)](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.Designer.html) 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.

```csharp
private void RemoveSelectedItems()
{
  _designer.ExecuteAction(DesignerAction.EditDelete);
}
```

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

```csharp
private void Clear()
{
  _designer.ExecuteAction(DesignerAction.SelectAll);
  _designer.ExecuteAction(DesignerAction.EditDelete);
}
```

### Supply credentials for a data provider

Use the [Designer.LocateCredentials](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.Designer.html) event to provide credentials for data providers as demonstrated in the code example.

```csharp.
using System.Windows.Forms;
using GrapeCity.ActiveReports;
using GrapeCity.ActiveReports.Design;
```

```csharp
_designer.LocateCredentials += (sender, args) => {
  args.UserName = "sa";
  args.Password = "12345";
}
```

### Provide data for a page report

Use the [Designer.LocateDataSource](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.Designer.html) event to provide data for previewing a page report as demonstrated in the code example.

```csharp
_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](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.Designer.html) property or the [Designer.SelectionChanged](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.Designer.html) event to react to selection changes. Using the [Designer.Selection](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.Designer.html) 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.

```csharp
_designer.SelectionChanged += () {
  removeButton.Enabled =
    _designer.Selection.OfType<ReportItem>().Count() > 0
    || designer.Selection.OfType<ARControl>().Count() > 0;
}
```

### Get the changed undo history

The [UndoManager.Changed](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.UndoManager.html) 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](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.UndoManager.html) and [UndoManager.RedoCount](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.UndoManager.html) properties to set the Undo/Redo buttons state as shown in the code example.

```csharp
_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](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.Designer.html) event, you can execute some actions right after the layout has been changed as in the code example below.

```csharp
_designer.LayoutChanged += (sender, args) => {
  //do some work here
};
```

### Handle report layout changes

The [Designer.LayoutChanging](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.Designer.html) event allows to handle the report layout changes. The example below deprecates adding a new control without a dataset.

```csharp
_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)](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.Designer.html) method, you can check if a specific action in the Designer is enabled.

```csharp
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](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.Designer.html) property returns a currently opened report, which can be a Page report or a Section report.


> type=note
> To set a report, you should use the [Designer.LoadReport](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.Designer.html) method.

```csharp
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](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.Designer.html) 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.

```csharp
_designer.ReportChanged += (sender, args) => {
  saveButton.Enabled = true;
};
```

### Show the Data Source creation wizard

The [Designer.RunDataWizard](/activereportsnet/api/v19.2/MESCIUS.ActiveReports.Design.Win/GrapeCity.ActiveReports.Design.Designer.html) event opens the data source creation wizard.

```csharp
private void RunDataWizardButtonClick(object sender, EventArgs e)
{
    _designer.RunDataWizard();
}
```