ページレポート/RDLレポートでは、ファイルパスを使用することでファイルシステム上のリソースを解決することができますが、ケースによっては、リソースがデータベースなどの特殊なソースに保存されていることがあります。RDLレポートでは、カスタムリソースロケータを使用することで、レポートに必要なリソースをどのようなタイプの場所からも読み込むことができます。カスタムリソースロケータは、画像やテーマファイルなどのリソースや、ドリルスルーリンク、サブレポート、マスターレポートで使用するレポートに使用することができます。
カスタムリソースロケータを実装するには、GrapeCity.ActiveReports.ResourceLocatorクラスを継承してGetResourceメソッドをオーバーライドします。
GetResourceメソッドは、ParentUriプロパティとValueプロパティを返します。Valueプロパティには、見つかったリソースのメモリストリームが含まれます。ParentUriプロパティには、リソース階層内にあるリソースの親のURI文字列が含まれています。
製品サンプルにおけるGetResourceメソッドの使用例を以下に示します。
C# (MyPicturesLocator.cs)
C#コード (クラス内に貼り付けます) |
コードのコピー
|
---|---|
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 { /// My Picturesフォルダでリソースを検索するResourceLocatorの実装 internal sealed class MyPicturesLocator : ResourceLocator { private const string UriSchemeMyImages = "MyPictures:"; /// リソースを取得して返します。リソースが見つからない場合はnullを返します。 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; } /// My Picturesフォルダから指定した画像を含むストリームを返します。画像が見つからない場合はnullを返します。 /// pathパラメータは、My Picturesで見つかった画像のURL(例: 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) /// ファイルが有効な画像でないか、GDI+がこの画像タイプをサポートしていません。 { return null; } catch(ExternalException) /// 画像が保存できません。 { return null; } return stream; } } } |
Visual Basic (MyPicturesLocator.vb)
Visual Basicコード (クラス内に貼り付けます) |
コードのコピー
|
---|---|
Imports GrapeCity.ActiveReports.Extensibility Imports System.Globalization Imports System.IO Imports System.Runtime.InteropServices Public Class MyPicturesLocator Inherits ResourceLocator Const UriSchemeMyImages As String = "MyPictures:" ' リソースを取得して返します。リソースが見つからない場合はnullを返します。 ' resourceInfoパラメータには、取得するリソースに関する情報が含まれます。 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 ' ファイルが有効な画像でないか、GDI+がこの画像タイプをサポートしていません。 Return Nothing Catch ex As ExternalException ' 画像が保存できません。 Return Nothing End Try Return stream End Function End Class |
製品とともにインストールされたSamplesフォルダの以下の場所にカスタムリソースロケータのサンプルがあります。
<User Folder>\ActiveReportsNET18\Samples\Advanced\PageAndRDL\CustomResourceLocator\C#
<User Folder>\ActiveReportsNET18\Samples\Advanced\PageAndRDL\CustomResourceLocator\VB.NET
このサンプルには、現在のユーザーのMy Picturesフォルダでファイルを検索するカスタムリソースロケータが含まれます。ここでは特殊なMyPicturesプロトコルが使用されています。