共用方式為


建立自訂報表項目執行階段元件

自訂報表項目執行階段元件會使用任何 CLS 相容語言而實作為 Microsoft .NET Framework 元件,並在執行階段由報表處理器呼叫。您可藉由修改自訂報表項目對應的設計階段元件,在設計環境中定義執行階段元件的屬性。

如需完全實作自訂報表項目的範例,請參閱<SQL Server Reporting Services 產品範例>(英文)。

定義和執行個體物件

在實作自訂報表項目之前,了解「定義物件」(Definition Object) 和「執行個體物件」(Instance Object) 之間的差異很重要。定義物件提供自訂報表項目的 RDL 表示法,而執行個體物件是定義物件的評估版本。報表上每個項目只有一個定義物件。在包含運算式的定義物件上存取屬性時,您會取得未評估過的運算式字串。執行個體物件包含已評估的定義物件版本,而且與項目的定義物件可能具有一對多的關聯性。例如,如果報表具有 Tablix 資料區,而該資料區在詳細資料列中包含 CustomReportItem,則只會有一個定義物件,但資料區中的每個資料列都會有一個執行個體物件。

實作 ICustomReportItem 介面

若要建立 CustomReportItem 執行階段元件,您需要實作定義於 Microsoft.ReportingServices.ProcessingCore.dll 的 ICustomReportItem 介面:

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

在實作 ICustomReportItem 介面之後,將為您產生兩個方法 Stub:GenerateReportItemDefinitionEvaluateReportItemInstance。系統會先呼叫 GenerateReportItemDefinition 方法,並用它來設定定義屬性及建立 Image 物件,此物件將同時包含用於轉譯項目的定義屬性和執行個體屬性。在評估定義物件之後會呼叫 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 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;
        }
    }
}