[]
The End User Designer API for WinForms allows you to perform common operations with a report using the Designer class.
Use Designer.NewReport method to create a new empty report and initialize the Designer as shown in the code example.
using System.Windows.Forms;
using GrapeCity.ActiveReports.Design;
var _designer = new Designer() { Dock = DockStyle.Fill };
_designer.NewReport(DesignerReportType.RdlMultiSection);
Controls.Add(_designer);
type=note
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.
Use the Designer.LoadReport 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 to any storage by passing the XmlWriter object to the Designer.SaveReport method. See the example code for details.
using System.IO;
using System.Xml;
using GrapeCity.ActiveReports.Design;
private void SaveReport(Stream outStream)
{
using(var writer = XmlWriter.Create(outStream))
{
_designer.SaveReport(writer);
}
}
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.
using GrapeCity.ActiveReports;
using GrapeCity.ActiveReports.Design;
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;
}
}
class MyDesignerForm : Form
{
public MyDesignerForm()
{
InitializeComponent();
//The designer must be added to the form with the name '_designer'.
_designer.FontResolver = new DirectoryFontResolver("c:\\Fonts");
}
}
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.
using System;
using System.IO;
using System.Drawing;
using GrapeCity.ActiveReports;
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();
}
}
class MyDesignerForm : Form
{
public MyDesignerForm()
{
InitializeComponent();
//The designer must be added to the form with the name '_designer'.
_designer.ResourceLocator = new MyResourceLocator();
}
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.
private void RemoveSelectedItems()
{
_designer.ExecuteAction(DesignerAction.EditDelete);
}
The code example below demonstrates how you can select all items and remove them.
private void Clear()
{
_designer.ExecuteAction(DesignerAction.SelectAll);
_designer.ExecuteAction(DesignerAction.EditDelete);
}
Use the Designer.LocateCredentials event to provide credentials for data providers as demonstrated in the code example.
using System.Windows.Forms;
using GrapeCity.ActiveReports;
using GrapeCity.ActiveReports.Design;
_designer.LocateCredentials += (sender, args) => {
args.UserName = "sa";
args.Password = "12345";
}
Use the Designer.LocateDataSource event to provide data for previewing a page report as demonstrated in the code example.
_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." } };
}
};
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.
_designer.SelectionChanged += () {
removeButton.Enabled =
_designer.Selection.OfType<ReportItem>().Count() > 0
|| designer.Selection.OfType<ARControl>().Count() > 0;
}
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.
_designer.UndoManager.Changed += (sender, e) => {
_undoButton.Enabled = _designer.UndoManager.UndoCount > 0;
_redoButton.Enabled = _designer.UndoManager.RedoCount > 0;
};
With the Designer.LayoutChanged event, you can execute some actions right after the layout has been changed as in the code example below.
_designer.LayoutChanged += (sender, args) => {
//do some work here
};
The Designer.LayoutChanging event allows to handle the report layout changes. The example below deprecates adding a new control without a dataset.
_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;
}
};
With the Designer.QueryActionEnabled(DesignerAction) method, you can check if a specific action in the Designer is enabled.
var canConvert = designer.QueryActionEnabled(DesignerAction.ConvertToMaster);
//canConvert value will be 'false' for master reports and 'true' for rdl reports.
The Designer.Report 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 method.
var extension = switch designer.Report {
PageReport => ".rdlx",
SectionReport => ".rpx",
_ => throw new Exception("Unknown report type.")
};
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.
_designer.ReportChanged += (sender, args) => {
saveButton.Enabled = true;
};
The Designer.RunDataWizard event opens the data source creation wizard.
private void RunDataWizardButtonClick(object sender, EventArgs e)
{
_designer.RunDataWizard();
}