Hello,
I have been having a problem trying to generate a report programatically. I can generate columns just fine, but when it comes to trying to generate the rows, the ReportViewer gives me a NullReferenceException: "Object reference not set to an instance of an object." As I iterate through my list, I add a new row to the table body. Then, for every cell that needs to be made, I add a ChildGroup to the main Rowgroup. After I've finished iterating and generating everything, I finally add the parent RowGroup. From what I can tell, the way I add rows is close to the way it's done in the designer files. Here is the code in question:
private void table1_ItemDataBinding(object sender, EventArgs e){ HtmlTextBox textboxGroup; var christieTable = new ChristieTable(ReportParameters["partNumber"].Value.ToString(), ReportParameters["lotNumber"].Value.ToString()); var christieProps = typeof(ChristieTable).GetProperties(); table1.ColumnGroups.Clear(); table1.RowGroups.Clear(); table1.Body.Columns.Clear(); table1.Body.Rows.Clear(); TableGroup rowsTableGroup = new TableGroup(); List<ReportItemBase> reportItems = new List<ReportItemBase>(); //start at -1 so we can account for the mold # column but retain the ability to index using i for (int columnIndex = -1; columnIndex < christieProps.Length - 1; columnIndex++) { var propValue = (columnIndex != -1) ? (List<Tuple<double, int>>) christieProps[columnIndex].GetValue(christieTable) : null; //make sure our column property is populated if (propValue != null && propValue.Count > 0) { var columnsPerStation = 1; var currentDip = propValue[0].Item2; foreach (var measurePair in propValue) { if (measurePair.Item2 != currentDip) { columnsPerStation++; currentDip = measurePair.Item2; } } var tableGroupColumn = new TableGroup(); table1.ColumnGroups.Add(tableGroupColumn); //if tableGroupColumn isn't given a name, all cells will have the same value as cell 0,0 tableGroupColumn.Name = columnIndex.ToString(); table1.Body.Columns.Add(new TableBodyColumn(Unit.Inch(1))); for (int a = 0; a < columnsPerStation; a++) { textboxGroup = ReportHelper.GenStandardColumnHeader(christieTable.StationNames[columnIndex] + " - DIP NUMBER " + propValue[0].Item2); tableGroupColumn.ReportItem = textboxGroup; reportItems.Add(textboxGroup); } var value = (List<Tuple<double, int>>) christieProps[columnIndex].GetValue(christieTable, null); table1.Body.Rows.Add(new TableBodyRow(Unit.Inch(0.24998027086257935D))); for (int rowIndex = 0; rowIndex < 5; rowIndex++) { TableGroup newRowSubGroup = new TableGroup(); newRowSubGroup.Name = "row" + (columnIndex + rowIndex + 1).ToString(); rowsTableGroup.ChildGroups.Add(newRowSubGroup); HtmlTextBox newTextBoxTable = ReportHelper.GenTextBox(value[rowIndex].Item1.ToString()); table1.Body.SetCellContent(rowIndex, columnIndex + 1, newTextBoxTable); reportItems.Add(newTextBoxTable); } } else if (propValue == null) { var tableGroupColumn = new TableGroup(); table1.ColumnGroups.Add(tableGroupColumn); tableGroupColumn.Name = columnIndex.ToString(); table1.Body.Columns.Add(new TableBodyColumn(Unit.Inch(1))); textboxGroup = ReportHelper.GenStandardColumnHeader("MOLD #"); tableGroupColumn.ReportItem = textboxGroup; reportItems.Add(textboxGroup); HtmlTextBox textBoxTable = ReportHelper.GenTextBox("= RowNumber()"); table1.Body.SetCellContent(0, columnIndex + 1, textBoxTable); reportItems.Add(textBoxTable); } } rowsTableGroup.Name = "rowsGroup"; rowsTableGroup.Groupings.Add(new Grouping(null)); table1.RowGroups.Add(rowsTableGroup); table1.Items.AddRange(reportItems.ToArray());}
The GenStandardColumnHeader and GenTextBox methods simply return pre-formatted textboxes, their first parameter being the value of the textbox. The properties of the object ChristieTable that I am iterating through are DataMembers consisting of a list of pairs. Using the debugger, I found that the report processes fine, but throws the exception when trying to render. Despite the fact that rows get clearly added, I found in the debugger that the row count for the table at render time is 0. Any help would be appreciated, thanks.