[WPF] ReportViewerのUserControlサンプル

#はじめに
Livetでレポートを作成するのに簡単にできないか検討したが、UserControlを使いプロパティを設定することで比較的簡単にレポートを表示できるようになった。
メッセンジャーでできないか調べてみたがUserControlのほうで実現できた。
あまり、LivetでのReportViewerの事例が見当たらなかったので掲載する。

#ユーザーコントロール

```xml: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>
```

```csharp: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クラスを使いデータのやり取りを行う。

```csharp: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()
        {
        }
    }

```

```xml:MainWindow.xaml
    <Grid>
        <Controls:ReportControl DataSource="{Binding ReportData}" />
    </Grid>
```