ページレポート/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>\ActiveReportsNET14\Samples\Advanced\PageAndRDL\CustomResourceLocator\C#<User Folder>\ActiveReportsNET14\Samples\Advanced\PageAndRDL\CustomResourceLocator\VB.NET
このサンプルには、現在のユーザーのMy Picturesフォルダでファイルを検索するカスタムリソースロケータが含まれます。ここでは特殊なMyPicturesプロトコルが使用されています。