ActiveReports を WPF で使ってみる

#2014/07/30 追記: ActiveReports for .NET 最新版7.0J は WPF に対応しました。詳しくは以下をご覧ください。
ActiveReports for .NET 7.0J 新機能 WPFビューワ

グレープシティ ActiveReports for .NET 7.0J スタンダード 1開発LP

グレープシティ ActiveReports for .NET 7.0J スタンダード 1開発LP


ActiveReportsWPF で使ってる方って果たしてどれくらいおられるのでしょうか。私が調べたところ、WPF で ActiveReports を使うには、現状では WindowsFormsHost を使って相互運用するしか方法がないようです。(相互運用せず使う方法知ってる方いたら、ぜひ教えてくださいです m(_ _)m)
そこで WindowsFormsHost を使ってプレビューを表示してみました。ちなみに開発環境は XP SP3/VS2008、ActiveReports は ActiveReports 3.0 を使ってます。(予算がないため 6.0 に上げられない(;_;) )


WPF Window で ActiveReports を使ってみたの図


まずメニュー「プロジェクト」→「新しい項目の追加」をクリック(もしくは Ctrl+Shift+A)、「新しい項目の追加」ダイアログで「ActiveReports 3.0 ファイル」を選択して「追加」ボタンをクリック。プロジェクトに NewActiveReport1.vb が追加されます。

次に XAML の定義。レイアウトコンテナを Grid から WindowsFormsHost に変更します。あと起動時に画面を最大化するため、WindowState プロパティを Maximized にしています。

Window1.xaml

<Window x:Class="Window1"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	Title="Window1" Height="300" Width="300" 
	WindowState="Maximized" WindowStartupLocation="CenterScreen">
	<WindowsFormsHost Name="WindowsFormsHost1" />
</Window>


次にコードを実装します。ここでのポイントは Window.Closed イベント。このイベント内で レポートとビュアーを Dispose すると同時に WindowsFormsHost1.Child に Null を設定します。
特に Closed イベント内で

WindowsFormsHost1.Child = Nothing

の一行がないと、アプリケーション終了時に NullReferenceException 例外が発生するので、注意が必要です。

Window1.xaml.vb

Option Explicit On
Option Strict On

Imports DataDynamics.ActiveReports
Imports DataDynamics.ActiveReports.Viewer

Public Class Window1

	Private _report As ActiveReport3
	Private _viewer As Viewer

	Private Sub Window2_Initialized( _
			ByVal sender As Object, _
			ByVal e As System.EventArgs) Handles Me.Initialized

		_report = New NewActiveReport1()
		_report.Run()

		_viewer = New Viewer()
		_viewer.Document = _report.Document

		WindowsFormsHost1.Child = _viewer

	End Sub

	Private Sub Window2_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Closed
		WindowsFormsHost1.Child = Nothing
		_report.Dispose()
		_viewer.Dispose()
	End Sub

End Class

#2011/01/13 追記

以下のように、XAML 内にWinForm のコントロール定義できるのですね。知らなかった(汗


Window1.xaml

<Window x:Class="Window1"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:vw="clr-namespace:DataDynamics.ActiveReports.Viewer;assembly=ActiveReports.Viewer3"
	Title="Window1" Height="300" Width="300" 
	WindowState="Maximized" WindowStartupLocation="CenterScreen">
	<WindowsFormsHost>
		<vw:Viewer x:Name="_viewer" Dock="Fill"/>
	</WindowsFormsHost>
</Window>


Window1.xaml.vb

Option Explicit On
Option Strict On

Imports DataDynamics.ActiveReports

Public Class Window1

	Private _report As ActiveReport3

	Private Sub Window1_Initialized( _
			ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Initialized

		_report = New NewActiveReport1()
		_report.Run()
		_viewer.Document = _report.Document
	End Sub

	Private Sub Window1_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Closed
		_report.Dispose()
	End Sub

End Class