Crear un componente de tiempo de ejecución de elemento de informe personalizado
El componente de tiempo de ejecución del elemento de informe personalizado se implementa como un componente Microsoft .NET Framework utilizando cualquier lenguaje compatible con CLS y el procesador del informe lo llama en el tiempo de ejecución. Las propiedades para el componente de tiempo de ejecución en el entorno de diseño se definen modificando el componente de tiempo de diseño correspondiente del elemento de informe personalizado.
Para obtener una muestra de un elemento de informe personalizado implementado totalmente, vea Muestras de productos de SQL Server Reporting Services.
Objetos de definición e instancia
Antes de implementar un elemento de informe personalizado, es importante entender la diferencia entre los objetos de definición y objetos de instancia. Los objetos de definición proporcionan la representación RDL del elemento de informe personalizado mientras que objetos de instancia son las versiones evaluadas de los objetos de definición. Hay solo un objeto de definición para cada elemento en el informe. Al tener acceso a las propiedades en un objeto de definición que contiene expresiones, obtendrá una cadena de expresión no evaluada. Los objetos de instancia contienen las versiones evaluadas de los objetos de definición y pueden tener una relación uno a varios con el objeto de definición de un elemento. Por ejemplo, si un informe tiene una región de datos Tablix que contiene un CustomReportItem en una fila de detalle, solo habrá un objeto de definición, pero habrá un objeto de instancia para cada fila en la región de datos.
Implementar la interfaz ICustomReportItem
Para crear un componente de tiempo de ejecución CustomReportItem, necesitará implementar la interfaz ICustomReportItem que se define en Microsoft.ReportingServices.ProcessingCore.dll:
namespace Microsoft.ReportingServices.OnDemandReportRendering
{
public interface ICustomReportItem
{
void GenerateReportItemDefinition(CustomReportItem customReportItem);
void EvaluateReportItemInstance(CustomReportItem customReportItem);
}
}
Después de haber implementado la interfaz ICustomReportItem, se generarán dos códigos auxiliares de método: GenerateReportItemDefinition y EvaluateReportItemInstance. El método GenerateReportItemDefinition se llama primero y se utiliza para establecer las propiedades de definición y crear el objeto Image que contendrá las propiedades de instancia y definición que se utilizan para representar el elemento. Se llama al método EvaluateReportItemInstance una vez evaluados los objetos de definición, y este método proporciona los objetos de instancia que se utilizarán para representar el elemento.
La siguiente es una implementación de ejemplo de un elemento de informe personalizado que representa el nombre del control como una imagen.
namespace Microsoft.Samples.ReportingServices
{
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
using Microsoft.ReportingServices.OnDemandReportRendering;
public class PolygonsCustomReportItem : ICustomReportItem
{
#region ICustomReportItem Members
public void GenerateReportItemDefinition(CustomReportItem cri)
{
// Create the Image object that will be
// used to render the custom report item
cri.CreateCriImageDefinition();
Image polygonImage = (Image)cri.GeneratedReportItem;
}
public void EvaluateReportItemInstance(CustomReportItem cri)
{
// Get the Image definition
Image polygonImage = (Image)cri.GeneratedReportItem;
// Create the image for the custom report item
polygonImage.ImageInstance.ImageData = DrawImage(cri);
}
#endregion
/// <summary>
/// Creates an image of the CustomReportItem's name
/// </summary>
private byte[] DrawImage(CustomReportItem customReportItem)
{
int width = 1; // pixels
int height = 1; // pixels
int resolution = 75; // dpi
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(width, height);
bitmap.SetResolution(resolution, resolution);
System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(bitmap);
graphics.PageUnit = System.Drawing.GraphicsUnit.Pixel;
// Get the Font for the Text
System.Drawing.Font font = new System.Drawing.Font(System.Drawing.FontFamily.GenericMonospace,
12, System.Drawing.FontStyle.Regular);
// Get the Brush for drawing the Text
System.Drawing.Brush brush = new System.Drawing.SolidBrush(System.Drawing.Color.LightGreen);
// Get the measurements for the image
System.Drawing.SizeF maxStringSize = graphics.MeasureString(customReportItem.Name, font);
width = (int)(maxStringSize.Width + 2 * font.GetHeight(resolution));
height = (int)(maxStringSize.Height + 2 * font.GetHeight(resolution));
bitmap.Dispose();
bitmap = new System.Drawing.Bitmap(width, height);
bitmap.SetResolution(resolution, resolution);
graphics.Dispose();
graphics = System.Drawing.Graphics.FromImage(bitmap);
graphics.PageUnit = System.Drawing.GraphicsUnit.Pixel;
// Draw the text
graphics.DrawString(customReportItem.Name, font, brush, font.GetHeight(resolution),
font.GetHeight(resolution));
// Create the byte array of the image data
MemoryStream memoryStream = new MemoryStream();
bitmap.Save(memoryStream, ImageFormat.Bmp);
memoryStream.Position = 0;
byte[] imageData = new byte[memoryStream.Length];
memoryStream.Read(imageData, 0, imageData.Length);
return imageData;
}
}
}