我正在使用Visual 2015构建一个应用程序。该应用程序需要在本地显示一些报告。
有以下两种解决办法:
虽然第一个是MVVM,但它将UI与视图模型混合在一起。第二种是纯代码隐藏。
下面是第一个例子所暗示的:
WindowsFormsHost windowsFormsHost = new WindowsFormsHost();
reportViewer = new ReportViewer();
windowsFormsHost.Child = reportViewer;
this.Viewer = windowsFormsHost注意,ReportViewer是一个UI控件。第二种解决方案使用代码隐藏文件:
private void ReportViewer_Load(object sender, EventArgs e)
{
//...
}是否有方法将本地SSRS报告嵌入WPF应用程序并遵循良好的MVVM实践?谢谢。
更新:不需要狂热!如果需要代码隐藏,我不介意。
发布于 2019-12-09 12:33:02
我们使用视图从ComboBox中选择报表,并使用按钮运行报表。在视图模型中,报表的ComboBox绑定到报表名称和ID的ObservableCollection。然后,我们使用MVVM轻型工具包的Messaging类发送/接收“消息”。注意,基本视图模型MyAppViewModelBase继承了Light的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");
}
}report视图有一个名称为WindowsFormsHost的ReportViewer,在上面的代码隐藏中引用:
<WindowsFormsHost Width="Auto" Height="500">
<rv:ReportViewer x:Name="ReportViewer" />
</WindowsFormsHost>https://stackoverflow.com/questions/37885160
复制相似问题