首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MVVM中的ReportViewer

MVVM中的ReportViewer
EN

Stack Overflow用户
提问于 2016-06-17 15:21:26
回答 1查看 3.1K关注 0票数 6

我正在使用Visual 2015构建一个应用程序。该应用程序需要在本地显示一些报告。

有以下两种解决办法:

虽然第一个是MVVM,但它将UI与视图模型混合在一起。第二种是纯代码隐藏。

下面是第一个例子所暗示的:

代码语言:javascript
复制
WindowsFormsHost windowsFormsHost = new WindowsFormsHost();
reportViewer = new ReportViewer();
windowsFormsHost.Child = reportViewer;
this.Viewer = windowsFormsHost

注意,ReportViewer是一个UI控件。第二种解决方案使用代码隐藏文件:

代码语言:javascript
复制
private void ReportViewer_Load(object sender, EventArgs e)
{
   //...
}

是否有方法将本地SSRS报告嵌入WPF应用程序并遵循良好的MVVM实践?谢谢。

更新:不需要狂热!如果需要代码隐藏,我不介意。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-12-09 12:33:02

我们使用视图从ComboBox中选择报表,并使用按钮运行报表。在视图模型中,报表的ComboBox绑定到报表名称和ID的ObservableCollection。然后,我们使用MVVM轻型工具包Messaging类发送/接收“消息”。注意,基本视图模型MyAppViewModelBase继承了Light的ViewModelBase,后者定义了RaisePropertyChanged()

还请注意,我们可以传递所选报表的VM,而不是视图的VM;这将更有效,但需要对此代码进行修改。然后,我们将为所有报表VM使用一个基类,并在代码隐藏中使用模式匹配开关来选择要运行的报表。

以下是视图模型的相关代码:

代码语言:javascript
复制
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;
    }
}

在视图的代码背后:

代码语言:javascript
复制
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视图有一个名称为WindowsFormsHostReportViewer,在上面的代码隐藏中引用:

代码语言:javascript
复制
<WindowsFormsHost Width="Auto" Height="500">                   
    <rv:ReportViewer x:Name="ReportViewer" />
</WindowsFormsHost>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37885160

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档