はじめに
Livetでレポートを作成するのに簡単にできないか検討したが、UserControlを使いプロパティを設定することで比較的簡単にレポートを表示できるようになった。
メッセンジャーでできないか調べてみたがUserControlのほうで実現できた。
あまり、LivetでのReportViewerの事例が見当たらなかったので掲載する。
ユーザーコントロール
ReportControl.xaml
<UserControl x:Class="Sample.Controls.ReportControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:rv="clr-namespace:Microsoft.Reporting.WinForms;assembly=Microsoft.ReportViewer.WinForms"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<WindowsFormsHost>
<rv:ReportViewer x:Name="_reportViewer" />
</WindowsFormsHost>
</Grid>
</UserControl>
ReporControl.xaml.cs
using Microsoft.Reporting.WinForms;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
namespace Sample.Controls
{
public class ReportArgument
{
public ReportDataSource DataSource {get; set;}
public string ResourceName {get; set;}
public ReportArgument (string dataSourceName,
object dataSource, string resourceName)
{
DataSource = new ReportDataSource(dataSourceName, dataSource);
ResourceName = resourceName;
}
}
/// <summary>
/// ReportControl.xaml の相互作用ロジック
/// </summary>
public partial class ReportControl : UserControl
{
/// <summary>
/// DataSourceプロパティ
/// </summary>
public static readonly DependencyProperty DataSourceProperty =
DependencyProperty.Register(
"DataSource",
typeof(object),
typeof(ReportControl),
new PropertyMetadata(null, ValueChanged)
);
[Bindable(true)]
public object DataSource
{
get { return GetValue(DataSourceProperty); }
set { SetValue(DataSourceProperty, value); }
}
public ReportControl()
{
InitializeComponent();
}
private static void ValueChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var obj = (ReportControl)d;
var val = e.NewValue as ReportArgument;
if (val == null)
return;
obj.SetReportData(val);
}
private void SetReportData(ReportArgument reportData)
{
if (reportData == null)
return;
var dsrc = _reportViewer.LocalReport.DataSources;
while (dsrc.Count > 0)
dsrc.RemoveAt(0);
dsrc.Add(reportData.DataSource);
_reportViewer.LocalReport.ReportEmbeddedResource = reportData.ResourceName;
_reportViewer.RefreshReport();
}
}
}
使い方
ReportArgumentクラスを使いデータのやり取りを行う。
MainWindowViewModel.cs
public class MainWindowViewModel : ViewModel
{
private DSet DSet = AppContext.Instance.DSet;
#region ReportData変更通知プロパティ
private ReportArgument _ReportData;
public ReportArgument ReportData
{
get
{ return _ReportData; }
set
{
if (_ReportData == value)
return;
_ReportData = value;
RaisePropertyChanged();
}
}
#endregion
public MainWindowViewModel()
{
ReportData =
new ReportArgument("DataSet1", DSet.WK,
"Sample.Reports.Report.rdlc");
}
public void Initialize()
{
}
}
MainWindow.xaml
<Grid>
<Controls:ReportControl DataSource="{Binding ReportData}" />
</Grid>