C# Winform - How to display real time reports by passing 3 variables to ReportViewer namely Reportname(RDL file), SQLstring and Connectionstring

ぃ、小莉子 提交于 2019-12-02 01:33:29

You can use a single ReportForm like below and pass data and report name to it. The report form should contain a ReportViewer control and such code:

public partial class ReportForm : Form
{
    public ReportForm()
    {
        InitializeComponent();
        this.Load+=new EventHandler(ReportForm_Load);
    }

    public Object ReportData { get; set; }
    public string ReportName { get; set; }        

    private void ReportForm_Load(object sender, EventArgs e)
    {
        var rds = new Microsoft.Reporting.WinForms.ReportDataSource("DataSet1",
            this.ReportData);
        this.reportViewer1.LocalReport.DataSources.Clear();
        this.reportViewer1.LocalReport.DataSources.Add(rds);         
        var path = System.IO.Path.Combine(Application.StartupPath, 
            "Reports", this.ReportName);
        reportViewer1.LocalReport.ReportPath = path;
        this.reportViewer1.RefreshReport();
    }
}

Usage

You can use the ReportForm this way:

var f = new ReportForm();
DataTable table = new DataTable(); 
var command = Properties.Settings.Default.Command;        /*SELECT Statement*/
var connection = Properties.Settings.Default.Connection;  /*Connection String*/
using (var adapter = new SqlDataAdapter(command, connection))
    adapter.Fill(table)
f.ReportName = "Report1.rdlc" /*Or any other name*/
f.ReportData = table;
f.ShowDialog();

Note

  1. ReportViewer control shows RDLC reports. RDL Reports should be hosted on SQL Server Reporting Service. It seems you want to have report on client machines and not on a SSRS. If this is the case you need RDLC report. Although RDL and RDLC have the same XML schema but technically it seems you need RDLC.

  2. You said RDL file is generally designed once So clients can have report files on their machines and you can simply load a report into report view by its address, or even you can have those reports in solution and embed them as resources. You can load report by its name when you set it as embedded resource:

    reportViewer1.LocalReport.ReportEmbeddedResource = "Sample.Reports.Report1.rdlc";
    

    Or load reports by path:

    var path = System.IO.Path.Combine(Application.StartupPath, "Reports", "Report1.rdlc");
    reportViewer1.LocalReport.ReportPath = path;
    
  3. You said The SQL is generally a constant. and Our users do not share connection with us So you can use a Settings.settings and add 2 properties, Command with Application scope, Connection with user scope. So you can let the users change the connection string at run-time and then load data this way and pass the data to your ReportForm:

    DataTable table = new DataTable(); 
    var command = Properties.Settings.Default.Command;
    var connection = Properties.Settings.Default.Connection;
    using (var adapter = new SqlDataAdapter(command, connection))
        adapter.Fill(table)
    //Pass table to ReportForm
    
  4. In fact the sql command can be dynamic, but it should keep a constant result schema. Result column name should not be changed because the report engine uses query column names to show data in report fields. So you can create your Command property as User settings too.

  5. About But a solution in any popular RDBMS, it's better to use dependency injection to inject libraries which load data for you. This way you can have different dll for different DBMS and inject suitable dll when you need.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!