ReportBuilder 2 で設計された RDL ファイルがあります。これを C# アプリケーションで表示する必要があります。gotreportviewer.com に RdlViewer の例があることは知っていますが、それは私が本当に望んでいるものではありません (たとえば、複数の値を持つパラメーターを処理することはできません)。代わりに、ReportBuilder 自体がレポートのプレビューを表示する方法に興味があります。そのインストール ディレクトリを調べると、興味深い DLL がいくつか見つかりました。ILSpy を使用すると、MSReportBuilder.exe 内に、ReportBuilder の [実行] ボタンをクリックすると呼び出される「StartPreview()」というメソッドがあることがわかりました。コードは次のとおりです。
private void StartPreview()
{
try
{
if (!this.m_layoutEditor.AtBookmark("ReportPreview"))
{
using (MemoryStream memoryStream = new MemoryStream())
{
this.m_layoutEditor.CommitPendingChanges(false);
this.m_preview.Reset();
Report report;
if (this.ActiveServer != null)
{
this.m_preview.ProcessingMode = ProcessingMode.Remote;
report = this.m_preview.ServerReport;
string text = this.ActiveServer.ServerUrl;
if (this.ActiveServer.IsInSharePointMode)
{
text = Util.RemoveTrailingSlash(text) + "/_vti_bin/reportserver";
}
AuthenticationInfo authenticationInfo = this.ActiveServer.GetAuthenticationInfo();
if (authenticationInfo.IsFormsAuth)
{
this.m_preview.ServerReport.ReportServerCredentials.SetFormsCredentials(authenticationInfo.AuthCookie, authenticationInfo.UserName, authenticationInfo.Password, authenticationInfo.Domain);
}
this.m_preview.ServerReport.ReportServerUrl = new Uri(text);
using (this.m_layoutEditor.UndoManager.BeginTempGroup())
{
Report rdlObject = this.m_layoutEditor.Report.GetRdlObject();
if (this.CurrentReportInfo.IsServerReport)
{
this.m_reportProject.ResolveServerReferences(rdlObject);
}
RdlSerializer rdlSerializer = LayoutEditor.CreateSerializer();
rdlSerializer.Serialize(memoryStream, rdlObject);
}
memoryStream.Position = 0L;
this.m_preview.ServerReport.LoadReportDefinition(memoryStream);
DataSourceCredentials[] storedCredentialsForCurrentReport = this.GetStoredCredentialsForCurrentReport();
if (storedCredentialsForCurrentReport.Length > 0)
{
this.m_preview.ServerReport.SetDataSourceCredentials(storedCredentialsForCurrentReport);
}
}
else
{
this.m_preview.ProcessingMode = ProcessingMode.Local;
report = this.m_preview.LocalReport;
using (this.m_layoutEditor.UndoManager.BeginTempGroup())
{
Report rdlObject2 = this.m_layoutEditor.Report.GetRdlObject();
this.m_reportProject.FixUpDataSourceCredentialsForLocalPreview(rdlObject2);
RdlSerializer rdlSerializer2 = LayoutEditor.CreateSerializer();
rdlSerializer2.Serialize(memoryStream, rdlObject2);
}
memoryStream.Position = 0L;
this.m_preview.LocalReport.LoadReportDefinition(memoryStream);
DataSourceCredentials[] storedCredentialsForCurrentReport2 = this.GetStoredCredentialsForCurrentReport();
if (storedCredentialsForCurrentReport2.Length > 0)
{
bool flag;
this.m_preview.LocalReport.GetDataSources(out flag);
if (!flag)
{
this.m_preview.LocalReport.SetDataSourceCredentials(storedCredentialsForCurrentReport2);
}
}
}
report.DisplayName = this.CurrentReportInfo.ReportName;
this.m_preview.RefreshReport();
this.m_layoutEditor.SetBookmark("ReportPreview");
}
}
}
catch (Exception ex)
{
string message;
this.m_reportProject.ParseException(ex, out message);
ErrorDialog.Show(this, Strings.Error_Preview, message, ex);
this.SetDisplayMode(DisplayMode.Design);
}
}
興味深い点は、サーバー側の処理のコードが非常に明確であることです。しかし、クライアント側の処理 (私のニーズ) がどのように機能するのか理解できません! 私のアプリケーションで同じことを行うのを手伝ってもらえますか?
私はVS 2010 / .Net 4.0を使用しています