页面报表和 RDL报表可以通过文件路径从您的文件系统中提取资源,但有时资源是一种非常特殊的形式,比如数据库。在 RDL 报表中,您可以创建自定义资源定位器,从任意位置读取任意资源供您的报表使用,比如:图像,主题文件,钻取链接报表、子报表或基准报表。
API
您可以通过从 ResourceLocator 类派生并重写 GetResource 方法来实现自定义资源定位器。
GetResource 方法返回 ParentUri 和 Value 属性。Value 包含定位到资源的内容流, ParentUri 属性包含层次结构资源中父级资源的 URI 字符串。
下面是使用 GetResource 方法的示例。
用 C# 代码实现 GetResource 方法
using System; using System.Collections.Generic; using System.Drawing; using System.Globalization; using System.IO; using System.Runtime.InteropServices; using System.Text; using GrapeCity.ActiveReports.Extensibility; using GrapeCity.ActiveReports.Samples.CustomResourceLocator.Properties; namespace GrapeCity.ActiveReports.Samples.CustomResourceLocator { /// Implementation of ResourceLocator which looks for resources in the My Pictures folder. internal sealed class MyPicturesLocator : ResourceLocator { private const string UriSchemeMyImages = "MyPictures:"; /// Obtains and returns the resource, or returns null if it is not found. public override Resource GetResource(ResourceInfo resourceInfo) { Resource resource; string name = resourceInfo.Name; if (name == null || name.Length == 0) { throw new ArgumentException(Resources.ResourceNameIsNull, "name"); } Uri uri = new Uri(name); if (uri.GetLeftPart(UriPartial.Scheme).StartsWith(UriSchemeMyImages, true, CultureInfo.InvariantCulture)) { Stream stream = GetPictureFromSpecialFolder(uri); if (stream == null) { stream = new MemoryStream(); Resources.NoImage.Save(stream, Resources.NoImage.RawFormat); } resource = new Resource(stream, uri); } else { throw new InvalidOperationException(Resources.ResourceSchemeIsNotSupported); } return resource; } /// Returns a stream containing the specified image from the My Pictures folder, or null if the picture is not found. /// The path parameter is the URI of the image located in My Pictures, e.g. MyImages:logo.gif private static Stream GetPictureFromSpecialFolder(Uri path) { int startPathPos = UriSchemeMyImages.Length; if (startPathPos >= path.ToString().Length) { return null; } string pictureName = path.ToString().Substring(startPathPos); string myPicturesPath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures); if (!myPicturesPath.EndsWith("\\")) myPicturesPath += "\\"; string picturePath = Path.Combine(myPicturesPath, pictureName); if (!File.Exists(picturePath)) return null; MemoryStream stream = new MemoryStream(); try { Image picture = Image.FromFile(picturePath); picture.Save(stream, picture.RawFormat); stream.Position = 0; } catch(OutOfMemoryException) /// The file is not a valid image, or GDI+ doesn't support the image type. { return null; } catch(ExternalException) /// The image can't be saved. { return null; } return stream; } } } |
用 Visual Basic .NET 代码实现 GetResource 用法
Imports GrapeCity.ActiveReports.Extensibility Imports System.Globalization Imports System.IO Imports System.Runtime.InteropServices Public Class MyPicturesLocator Inherits ResourceLocator Const UriSchemeMyImages As String = "MyPictures:" ' Obtains and returns the resource, or null if it is not found. ' The resourceInfo parameter contains the information about the resource to obtain. Public Overrides Function GetResource(ByVal resourceInfo As ResourceInfo) As Resource Dim resource As Resource Dim name As String = resourceInfo.Name
If (String.IsNullOrEmpty(name)) Then Throw New ArgumentException(My.Resources.ResourceNameIsNull, "name") End If Dim uri As New Uri(name) If (Uri.GetLeftPart(UriPartial.Scheme).StartsWith(UriSchemeMyImages, True, CultureInfo.InvariantCulture)) Then Dim stream As Stream = GetPictureFromSpecialFolder(uri) If (stream Is Nothing) Then stream = New MemoryStream() My.Resources.NoImage.Save(stream, My.Resources.NoImage.RawFormat) End If resource = New Resource(stream, uri) Else Throw New InvalidOperationException(My.Resources.ResourceSchemeIsNotSupported) End If Return resource End Function Function GetPictureFromSpecialFolder(ByVal path As Uri) As Stream Dim startPathPos As Integer = UriSchemeMyImages.Length If (startPathPos >= path.ToString().Length) Then Return Nothing End If Dim pictureName As String = path.ToString().Substring(startPathPos) Dim myPicturesPath As String = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) If (Not myPicturesPath.EndsWith("\\")) Then myPicturesPath += "\\" End If Dim picturePath As String = System.IO.Path.Combine(myPicturesPath, pictureName) If (Not File.Exists(picturePath)) Then Return Nothing End If Dim stream As New MemoryStream() Try Dim picture As Image = Image.FromFile(picturePath) picture.Save(stream, picture.RawFormat) stream.Position = 0 Catch ex As OutOfMemoryException ' The file is not a valid image, or GDI+ doesn't support the image type. Return Nothing Catch ex As ExternalException ' The image can't be saved. Return Nothing End Try Return stream End Function End Class |
示例
随产品一块安装的 Samples 文件夹中,您可以找到自定义资源定位器示例:
C:\Users\用户名\Documents\GrapeCity Samples\ActiveReports 9\Page Reports\RDL\API\C#\CustomResourceLocator