关于c#:从ReportViewer中的DataGridView显示数据源

Display DataSource from DataGridView in ReportViewer

在先前有关报表查看器中动态列的问题之后,我认为我至少会尝试使事情正常进行。
显示的输出是数学因子的列,每个因子都有自己的唯一名称。这些因素(可以选择1到10之间的任何数字)在我的DataGridView控件中显示没有问题-通过根据需要添加行/列来生成DataTable,然后将数据表设置为DataGridView的数据源。
我已经将ReportViewer添加到WinForm中,并生成了RDLC文件。我的RDLC不用花数小时试图弄清楚如何使其动态,而是设置了10列(据我所知,永远不会超过此列),并且将DataSet分配给了ReportViewer控件。然后,我使用以下代码将数据分配给查看器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
DataTable dt = new DataTable();
var source = this.dgvSelectedElements.DataSource;
while (source is BindingSource)
{
    source = ((BindingSource)source).DataSource;
}
var table = source as DataTable;
if (table != null)
{
    dt = table;
    var reportSource = new ReportDataSource("FactorReport", dt);
    this.reportViewer1.Reset();
    this.reportViewer1.ProcessingMode = ProcessingMode.Local;            
    this.reportViewer1.LocalReport.ReportPath ="FactorReport.rdlc";
    this.reportViewer1.LocalReport.DataSources.Clear();
    this.reportViewer1.LocalReport.DataSources.Add(reportSource);
    this.reportViewer1.RefreshReport();
}

因此,这是DataGridview的外观:
enter image description here
然后,这是Reportviewer-注意底部的两个" Rate"和" Mult"行
enter image description here
enter image description here
因此,尽管看起来可行,但我无法在网格中看到这些值。另外,当年龄超过100时,年龄分类不正确-可以关闭分类功能吗?并假设我可以使它起作用,是否可以遍历ReportViewer并修改列标题?一个快速的谷歌告诉我不是在运行时?


也许不是最好/最快的解决方案,但是它可以工作,并且对可见性表达式进行了一些其他更改,因此我只能显示已选择的列数。
我将10个参数添加到名为Factor_Name_1到Factor_Name_10的报表查看器中,并在创建它们时在属性中选中了"允许空值"。然后,我编写了一些代码以添加参数数据,存储现有的列名,然后将它们重命名为我的Factor1,Factor2 ... Factor10标题,如下所示(请注意,我并不担心在第一个" Age"列中):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
        // loop through the columns to create parameters...
        for (int i = 1; i < dt.Columns.Count; i++)
        {
            // get the name of the column...
            string factorName = dt.Columns[i].ColumnName;
            // define the new column name...
            string colName = string.Format("Factor_Name_{0}", i);
            // change the column name now we have stored the real name...
            dt.Columns[i].ColumnName = string.Format("Factor{0}", i);
            // generate the parameter...
            var rparam = new ReportParameter(colName, factorName);
            // add it to the parameter set for the control...
            this.reportViewer1.LocalReport.SetParameters(new[] { rparam });
        }

创建关联参数后,通过重新设置列名称,数据将正确绑定。在RDLC设计器中,我要做的就是用相关的参数值替换现有的标题。然后,为了隐藏未选中的列,我将"参数"和"行文本框"的可见性表达式设置为:

1
2
3
4
=IIF(ISNOTHING(Parameters!Factor_Name_1.Value),True,False)
....
....
=IIF(ISNOTHING(Parameters!Factor_Name_10.Value),True,False)

现在,如果我选择1或10列,查看器将显示正确的列数,并隐藏不需要的列。现在正在重复"年龄"列(已经重复了标题)并在运行时添加页眉/页脚,但是我目前有一个报告,以正确的标题显示我需要的数据。
With four items selected
With ten items selected
感谢@Reza Aghaei使我步入正轨。


您应该正确设置动态创建的DataTable中的列名称为DataGridViewDataSource。它们应该是AgeFactor1Factor2,...,Factor10

您使用这些列名称创建了报告。因此,当为网格动态创建DataTable时,应将列名称设置为与创建报表时使用的名称相同的名称。

如何获得相同的列名?

但是,您可以通过创建一个临时的DataTable来解决问题,该临时DataTable包含由原始数据表填充的Age,Factor1,...,Factor10。将此表传递给报告,它将起作用。

我如何在DataGridView中显示相同的列标题?

解决方案是将列标题作为参数。在报表设计器中创建10个参数,并使用参数设置报表中tablix列的标题,但不要更改列名。这些应该是AgeFactor1,...。然后,当您要显示报告时,除了上面提到的临时表,还应使用参数传递列标题。

另一个想法

另一个想法是,您可以使用完全相同的DataTable包含所有可用列的报表,然后,当您想在报表中显示某些列时,只需将一些参数传递给网格即可,以指示每列的可见性。