我们使用一个视图从ComboBox 中选择报告,并使用一个按钮来运行它。在视图模型中,我们将报告的ComboBox 绑定到报告名称和ID 的ObservableCollection。然后我们使用MVVM Light Toolkit 的Messaging 类来发送/接收“消息”。请注意,基本视图模型 MyAppViewModelBase 继承自 Light Toolkit 的 ViewModelBase,其中定义了 RaisePropertyChanged()。
另外请注意,我们可以传递所选报告的 VM 而不是视图的 VM;这会更有效,但需要修改此代码。然后,我们将使用所有报告 VM 的基类,并在代码隐藏中使用模式匹配开关来选择要运行的报告。
这是视图模型的相关代码:
using GalaSoft.MvvmLight.Messaging;
public class ReportsViewModel : MyAppViewModelBase
{
public ReportsViewModel()
{
// Register a listener that receives the enum of the
// report that's ready. The message it receives has
// name "SsrsReportReady" with handler SsrsReportReady.
Messenger.Default.Register<Constants.Report>(this, "SsrsReportReady", SsrsReportReady);
// Other logic...
}
// Bound to a button to run the selected report
public ICommand RunReportRelayCommand =>
new RelayCommand(RunReport);
// Backing field for the selected report.
private ReportViewModel _selectedReportVm;
public ReportViewModel SelectedReportVm
{
get { return _selectedReportVm; }
set
{
if (Equals(value, _selectedReportVm)) return;
_selectedReportVm = value;
// Built-in method from Light Toolkit to
// handle INotifyPropertyChanged
RaisePropertyChanged();
}
}
private void RunReport()
{
// Send a message called "RunSSRSReport" with this VM attached as its data.
Messenger.Default.Send(this, "RunSSRSReport");
}
// Handler for report-ready
private void SsrsReportReady(Constants.Report obj)
{
ShowReport = true;
IsRunReportButtonEnabled = true;
RunReportButtonContent = Constants.BtnGenerateReport;
// View uses Material Design's Expander control.
// We expand/collapse sections of the view.
ExpandReport = true;
ExpandParameters = false;
}
}
在视图的代码隐藏中:
using GalaSoft.MvvmLight.Messaging;
public partial class ReportsView : UserControl
{
public ReportsView()
{
InitializeComponent();
// Register a listener for the "RunSSRSReport"
// message, called from our viewmodel. Its
// handler is RunSsrsReport and its data type
// is ReportsViewModel.
Messenger.Default.Register<ReportsViewModel>(this, "RunSSRSReport", RunSsrsReport);
DataContext = new ReportsViewModel();
}
// Handler to run the selected report.
private void RunSsrsReport(ReportsViewModel obj)
{
// Basic validation
if (obj.SelectedReportVm == null || obj.SelectedReportVm.Id.Equals(-1))
{
return;
}
// Ugly switch to run the correct report.
// It can be re-written with pattern matching.
switch (obj.SelectedReportVm.Id)
{
case (int)Constants.Report.ReportA:
RunReportA(obj);
break;
case (int)Constants.Report.ReportB:
RunReportB(obj);
break;
// other reports....
}
}
// Run the report using dataset and tableadapter.
// Modify to use your code for running the report.
private void RunReportA(ReportsViewModel reportsViewModel)
{
var dataSet = new ReportADataSet();
dataSet.BeginInit();
// We reference the ReportViewer control in XAML.
ReportViewer.ProcessingMode = ProcessingMode.Local;
ReportViewer.LocalReport.ShowDetailedSubreportMessages = true;
ReportViewer.LocalReport.DataSources.Clear();
var dataSource = new ReportDataSource
{
Name = "ReportA_DS",
Value = dataSet.uspReportA // Uses a stored proc
};
ReportViewer.LocalReport.DataSources.Add(dataSource);
ReportViewer.LocalReport.ReportEmbeddedResource =
"MyApp.Reports.ReportA.rdlc";
dataSet.EndInit();
new reportATableAdapter { ClearBeforeFill = true }
.Fill(dataSet.uspReportA);
// Send message back to viewmodel that the report is ready.
Messenger.Default.Send(Constants.Report.ReportA, "SsrsReportReady");
}
}
报告视图有一个名为ReportViewer 的WindowsFormsHost,在上面的代码隐藏中引用:
<WindowsFormsHost Width="Auto" Height="500">
<rv:ReportViewer x:Name="ReportViewer" />
</WindowsFormsHost>