Поделиться через


Создание компонента времени выполнения пользовательского элемента отчета

Компонент времени выполнения пользовательского элемента отчета реализуется как компонент Microsoft.NET Framework с помощью любого CLS-совместимого языка и вызывается обработчиком отчетов во время выполнения. Свойства компонента времени выполнения в среде разработки задаются настройкой соответствующего компонента времени разработки пользовательского элемента отчета.

Дополнительные сведения об образе полностью реализованного пользовательского элемента отчета см. на странице Образцы продуктов служб SQL Server Reporting Services.

Объекты определения и объекты экземпляра

При разработке пользовательских элементов отчета важно понимать разницу между объектами определения и объектами экземпляра. Объекты определения обеспечивают представление пользовательских элементов отчета на языке определения отчетов, а объекты экземпляра являются версиями объектов определения с вычисленными выражениями. У каждого элемента отчета есть только один объект определения. При доступе к свойствам объекта определения, содержащего выражения, возвращается невычисленная строка выражения. Объекты экземпляра содержат вычисленные версии объектов определения и могут находиться в связи «один ко многим» с объектом определения элемента. Например, если в отчете есть область данных табликса, которая содержит пользовательский элемент отчета CustomReportItem в строке детализации, объект определения будет только один, но у каждой строки в этой области данных будет свой объект экземпляра.

Реализация интерфейса ICustomReportItem

Чтобы создать компонент времени выполнения CustomReportItem, необходимо реализовать интерфейс ICustomReportItem, определенный в динамической библиотеке Microsoft.ReportingServices.ProcessingCore.dll:

namespace Microsoft.ReportingServices.OnDemandReportRendering
{
    public interface ICustomReportItem
    {
        void GenerateReportItemDefinition(CustomReportItem customReportItem);
void EvaluateReportItemInstance(CustomReportItem customReportItem);
    }
}

После реализации интерфейса ICustomReportItem будут автоматически созданы две заглушки методов: GenerateReportItemDefinition и EvaluateReportItemInstance. Сначала вызывается метод GenerateReportItemDefinition. Он используется для задания свойств определения и создания объекта ImageDefinition, в котором будут содержаться свойства определения и свойства экземпляра, необходимые для подготовки к просмотру элемента отчета. Метод EvaluateReportItemInstance вызывается после вычисления объектов определения и предоставляет объекты экземпляра, которые будут использоваться для подготовки к просмотру элемента отчета.

Далее следует пример реализации пользовательского элемента отчета, который подготавливает к просмотру имя управляющего элемента в виде изображения.

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 Definition 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;
        }
    }
}