C# 当列/行发生变化时从Datatable创建报告

C# 当列/行发生变化时从Datatable创建报告,c#,winforms,datagridview,datatable,reportviewer,C#,Winforms,Datagridview,Datatable,Reportviewer,我已经做了很多搜索,但找不到任何有助于我开始这个问题的东西,所以我将尝试解释我的要求 我正在将一个遗留的VB6应用程序重新写入C#(Windows窗体),这使我们有机会删除未使用的方面,并添加一些新功能 遗留应用程序能够打印输出,但使用FORTRAN模块实现了这一点-我们不想使用这种旧技术,因此我正在寻找一种方法,获取DataGridView的数据源(可以轻松转换为Datatable)并以结构化格式打印 唯一一个让我难以找到如何发展这一点的例子的问题是,列的数量可以从1到10不等(如果他们决定增

我已经做了很多搜索,但找不到任何有助于我开始这个问题的东西,所以我将尝试解释我的要求

我正在将一个遗留的VB6应用程序重新写入C#(Windows窗体),这使我们有机会删除未使用的方面,并添加一些新功能

遗留应用程序能够打印输出,但使用FORTRAN模块实现了这一点-我们不想使用这种旧技术,因此我正在寻找一种方法,获取DataGridView的数据源(可以轻松转换为Datatable)并以结构化格式打印

唯一一个让我难以找到如何发展这一点的例子的问题是,列的数量可以从1到10不等(如果他们决定增加这一数量,则可以增加),并且标题在显示精算系数表时是唯一的

例如,第一行是表名,然后是任意数量的行(从40到95)

如果数据的结构中列标题是固定的,那么会有很多示例,但我找不到一个处理动态列的示例


应用程序开发已经在进行中,因此我希望使用VS(2012)中内置的ReportViewer,但找不到任何动态列的示例。我至少需要复制遗留版本的输出(如果需要,可以提供示例),如果不需要,还需要对其进行改进

下面是一个快速示例,说明如何动态创建列并将它们放置到
DataGridView

var dgv = new DataGridView();

var dgvTextColumn = new DataGridViewTextBoxColumn();
dgvTextColumn.Name = "columnName"; // to use for future column references
dgvTextColumn.DataPropertyName = "columnName"; // I prefer to keep this and .Name property the same
dgvTextColumn.HeaderText = "columnHeader";
dgvTextColumn.Width = 50;
dgvTextColumn.ReadOnly = false;
dgv.Columns.Add(dgvTextColumn);
这是一个非常简单的例子。我个人将要创建的列与一些基本列属性(如宽度、只读等)一起存储在数据库表中。循环遍历所有列,并通过上面的代码创建它们。通过这种方式,我可以在不重新编译应用程序的情况下更新要显示的列。我还根据要创建的列的类型,使用case语句对存储的列进行分解,以便可以执行组合、文本、按钮和复选框列

最重要的是,在动态创建列时,必须确保为
DataGridView
设置的数据源中存在
DataSourceName

var dgv = new DataGridView();

var dgvTextColumn = new DataGridViewTextBoxColumn();
dgvTextColumn.Name = "columnName"; // to use for future column references
dgvTextColumn.DataPropertyName = "columnName"; // I prefer to keep this and .Name property the same
dgvTextColumn.HeaderText = "columnHeader";
dgvTextColumn.Width = 50;
dgvTextColumn.ReadOnly = false;
dgv.Columns.Add(dgvTextColumn);

如果您想要更复杂的答案,请告诉我。

下面是一个快速示例,说明如何动态创建列并将它们放置到
DataGridView

var dgv = new DataGridView();

var dgvTextColumn = new DataGridViewTextBoxColumn();
dgvTextColumn.Name = "columnName"; // to use for future column references
dgvTextColumn.DataPropertyName = "columnName"; // I prefer to keep this and .Name property the same
dgvTextColumn.HeaderText = "columnHeader";
dgvTextColumn.Width = 50;
dgvTextColumn.ReadOnly = false;
dgv.Columns.Add(dgvTextColumn);
这是一个非常简单的例子。我个人将要创建的列与一些基本列属性(如宽度、只读等)一起存储在数据库表中。循环遍历所有列,并通过上面的代码创建它们。通过这种方式,我可以在不重新编译应用程序的情况下更新要显示的列。我还根据要创建的列的类型,使用case语句对存储的列进行分解,以便可以执行组合、文本、按钮和复选框列

最重要的是,在动态创建列时,必须确保为
DataGridView
设置的数据源中存在
DataSourceName

var dgv = new DataGridView();

var dgvTextColumn = new DataGridViewTextBoxColumn();
dgvTextColumn.Name = "columnName"; // to use for future column references
dgvTextColumn.DataPropertyName = "columnName"; // I prefer to keep this and .Name property the same
dgvTextColumn.HeaderText = "columnHeader";
dgvTextColumn.Width = 50;
dgvTextColumn.ReadOnly = false;
dgv.Columns.Add(dgvTextColumn);

如果您想要更复杂的答案,请告诉我。

您看到了吗?如果你正在更新一个遗留应用程序,为什么要使用VS2012和WinForms?虽然我意识到这不是最现代化的方式之一,但最容易使用且非常灵活的插件之一是Crystal Reports,你可以看看它@当制作轻量级数据管理应用程序或需要特定库时,Crowcoder Winforms仍然是首选WPF@KostasBalis,我对Crystal reports的经验比我想象的要多,我从来没有听过有人说这很容易。无论如何,OP使用的是rdlc(或者可能是rdl,它不太清楚)。@Crowcoder-谢谢,我有过,但最初拒绝了它,因为我不是从SQL获取数据-数据来自平面文本文件,加载到DataGridView中。我们一直使用C#WinForms的原因是为了确保我的团队中的开发人员都熟悉它,从而支持它。出于兴趣-您建议使用什么?@Kostas Balis-我曾考虑过Crystal Reports,但由于我已经进入开发阶段,并且没有安装它,所以我不清楚是否需要重新设计该项目?您看到了吗?如果你正在更新一个遗留应用程序,为什么要使用VS2012和WinForms?虽然我意识到这不是最现代化的方式之一,但最容易使用且非常灵活的插件之一是Crystal Reports,你可以看看它@当制作轻量级数据管理应用程序或需要特定库时,Crowcoder Winforms仍然是首选WPF@KostasBalis,我对Crystal reports的经验比我想象的要多,我从来没有听过有人说这很容易。无论如何,OP使用的是rdlc(或者可能是rdl,它不太清楚)。@Crowcoder-谢谢,我有过,但最初拒绝了它,因为我不是从SQL获取数据-数据来自平面文本文件,加载到DataGridView中。我们一直使用C#WinForms的原因是为了确保我的团队中的开发人员都熟悉它,从而支持它。出于兴趣-您建议使用什么?@Kostas Balis-我曾考虑过Crystal Reports,但由于我已经进入开发阶段,并且没有安装它,所以我不清楚是否需要重新设计该项目?谢谢@jaredbaszler。不过,填充datagridview不是我的问题——它能够获取源代码并打印我正在努力解决的内容。我查看了ReportViewer,发现示例“似乎”需要列的结构,并且由于我的内容可以是任意数量的列,每个列都有一个唯一的标题,因此似乎不适合。所以最终我想要的是关于从DGV源文件中打印的其他方法的建议。@MartinS-对于这个功能,我们使用Telerik的aweso