/// <summary> /// This prints out the contents of a datagrid using ReportBuilder /// </summary> /// <param name="reportDocument"></param> public void MakeDocument(ReportDocument reportDocument) { if (dataGrid == null) { return; } // We may need a DataSet and Data Table depending on DataGrid source type DataTable dataTable = new DataTable(); DataSet dataSet = new DataSet(); DataViewManager dataViewManager = new DataViewManager(); DataView dataView = new DataView(); // We may need to create a DataView depending on the type of DataSouce that is // in the DataGrid bool dataViewExpected = true; //Depending on the Source and if there is a valid data memember we may need //to create a dataView, We actually will try and get the dataView later on //from the currency manager as this will let us show the datatable if we //have drilled down. switch (dataGrid.DataSource.GetType().ToString()) { case "System.Data.DataViewManager": { #region //Check that a view is being shown, if no load views into a table if (dataGrid.DataMember == String.Empty) { dataViewExpected = false; //ok no Data View is active so print out he DataView dataTable = new DataTable("DataViewManager"); DataColumn dataColumn = dataTable.Columns.Add("TableID", typeof(String)); //Get the dataViewManger from the DataGrid source dataViewManager = (DataViewManager)dataGrid.DataSource; //Add a dataRow to our little table for each DataView Setting foreach (DataViewSetting dvs in dataViewManager.DataViewSettings) { dataTable.Rows.Add(new string[] { dvs.Table.TableName }); } //Now Create a DataView that the ReportPRinting can use to print dataView = new DataView(dataTable); } #endregion break; } case "System.Data.DataView": { dataView = (DataView)dataGrid.DataSource; break; } case "System.Data.DataTable": { dataView = ((DataTable)dataGrid.DataSource).DefaultView; break; } case "System.Data.DataSet": { #region //If DataGrid uses a Data set than the DataTable is in DataMember if (dataGrid.DataMember == String.Empty) { dataViewExpected = false; //ok no Data View is active so print out tables in DataSet //by first creating a dataTable and loading the dataSet Table names //into it so we can create a dataView dataTable = new DataTable("DataSetTables"); DataColumn dataColumn = dataTable.Columns.Add("TableID", typeof(String)); //Get the DataSet from the DataGrid source dataSet = (DataSet)dataGrid.DataSource; //Load the name of each table in the dataSet into our new table foreach (DataTable dt in dataSet.Tables) { dataTable.Rows.Add(new string[] { dt.TableName }); } //Now Create a DataView that the ReportPRinting can use to print dataView = new DataView(dataTable); } #endregion break; } } // See if we can pickup the current view from the currency manager // This should also pickup if we are drilled down on any relations etc // This will be skipped where there was no dataView obtainable from the // dataGrid dataSource and DataMember CurrencyManager currencyManager; if (dataViewExpected) { //Currency Manager for the DataGrid //if (dataGrid.BindingContext // [dataGrid.DataSource, dataGrid.DataMember] != null) //{ currencyManager = (CurrencyManager)dataGrid.BindingContext [dataGrid.DataSource, dataGrid.DataMember]; //This is the DataView that we are going to fill up... dataView = (DataView)currencyManager.List; //} } // Setup the document's settings reportDocument.DefaultPageSettings = pageSettings; reportBuilder.StartLinearLayout(Direction.Vertical); // Print out the actual Report Page #region page header/footer (replaced) /* * * %p is code for the page number * string pageStr = "-%p-"; * * string tableName=dataView.Table.TableName; * * reportBuilder.AddPageHeader( * // First page * pageStr, tableName , String.Empty, * // Right pages * pageStr, tableName , String.Empty, * // Odd pages * String.Empty, tableName, pageStr); * * reportBuilder.AddPageFooter (DateTime.Now.ToLongDateString(), ReportPrinting.HorizontalAlignment.Center); */ #endregion //Now lets print out the Datagrid - First the Heading reportBuilder.AddText(dataGrid.CaptionText, TextStyle.BoldStyle); #region parent relations (not needed) // We need to print any parent row info here // Check the dataGrid.DataMember and see if it is a data relation // If it is then get the first DataRow in the DataGrid and then // use its GetParentRows method, Each row should be checked to see // if there was a DataGridTableStyle set up for it // We have to work our way backwards up the data relation building strings that // need to be printed in reverse order to match the way the dataGrid displays if (dataGrid.ParentRowsVisible && //Are parents rows showing?? dataViewExpected && //If no view then skip this dataGrid.DataMember.LastIndexOf(".") > 0) //check Tablename.Relation { DataRowView dataRowView1 = dataView[0]; //first get the DataRow View DataRow dataRow1 = dataRowView1.Row; //Now get the DataRow for viewRow //break up the DataRelations string into its parts //[0] will be the original table,[1][..] will be relations //This need to be processed from last to first as the last one is //what is currently being displayed on the data grid string [] relations = dataGrid.DataMember.Split(new Char [] { '.' }); //we will build an array of strings of parent data showing on the //datagrid that needs to be printed in reverse order //of the way they were built on the DataGrid in order //to replicate the drill down on the data grid. string[] parentText = new string[relations.Length - 1]; //Go through each Relation from the last to first and get the parent rows //of the childRow using the data relations for that parent-child relation for (int r = relations.Length - 1; r > 0; r--) { //If a child has multiple parent rows than we need to figure out which //is parent for this drill down. To get the information for each //parent row we are going to build a string with table & relations //which is the same as the dataGrid Builds automatically on drilldown //for the DataMember field which we will store in parentMember. //parentMember will then be used to get the correct currencyManager //which in turn will get the correct dataview,dataRowView and DataRow //IE TABLENAME.RELATION1.RELATION2 etc string parentMember = String.Empty; for (int i = 0; i < r; i++) { parentMember += relations[i]; if (i < r - 1) { parentMember += "."; //Separate with periods except last } } //Now that we have the parentMember we need to get the currency //manager for that parentmember which is holding the current //DataView from which we will get the currencyManager = (CurrencyManager)dataGrid.BindingContext [dataGrid.DataSource, parentMember]; //This is the DataView that we are going to fill up... DataView parentDataView = (DataView)currencyManager.List; DataRowView parentDataRowView = (DataRowView)currencyManager.Current; //first get the DataRow View DataRow parentRow = parentDataRowView.Row; //Start with the TableName: parentText[r - 1] = parentRow.Table.TableName + ": "; // Determine if there is DataGrid Table Style for the parent table // or do we just go through all the columns in the parent DataTable try { DataGridTableStyle tableStyle = dataGrid.TableStyles[parentRow.Table.TableName]; //Go through the table style columns & build the parent text line foreach (DataGridColumnStyle columnStyle in tableStyle.GridColumnStyles) { parentText[r - 1] += columnStyle.MappingName + ": " + parentRow[columnStyle.MappingName].ToString() + " "; } } catch { //Go through the columns in the parentRow DataTable and built //the parent text line foreach (DataColumn dataColumn in parentRow.Table.Columns) { parentText[r - 1] += dataColumn.ColumnName + ": " + parentRow[dataColumn].ToString() + " "; } } } //Now print out all the Parent Text array using the report builder for (int i = 0; i < parentText.Length; i++) { reportBuilder.AddHorizontalLine(); reportBuilder.AddText(parentText[i], TextStyle.Normal); } reportBuilder.AddHorizontalLine(); } #endregion // Add dataView & all columns that are in the data grid reportBuilder.AddTable(dataView, true); // Now we have to determine if there was a DataGridTableStyle setup for this // DataGrid, The default will be to load from the DataView table columns bool loadFromDataView = true; //If there is a DataGridTableStyle - Add any columns showing in the grid.. foreach (DataGridTableStyle tableStyle in dataGrid.TableStyles) { //reportBuilder.AddTable(dataView, true);//dzs GraphicsUnit unit = reportDocument.DocumentUnit; //dzs Rectangle bounds = pageSettings.Bounds; //dzs System.Drawing.Printing.Margins margins = pageSettings.Margins; //dzs float availSpace = (bounds.Width - margins.Right - margins.Left) / 100; //dzs - should = 10 for landscape on 8.5x11 sheet float usedSpace = 0; //Keep running total if (tableStyle.MappingName == dataView.Table.TableName) { loadFromDataView = false; foreach (DataGridColumnStyle columnStyle in tableStyle.GridColumnStyles) { float maxWidth = (float)columnStyle.Width / 80; //Not sure if correct sizing usedSpace += maxWidth; if (usedSpace > availSpace) //this column will run off the page { usedSpace = 0; //Reset the space used reportBuilder.AddPageBreak(); //dzs //reportBuilder.FinishLinearLayout();//dzs //reportBuilder.StartLinearLayout(Direction.Vertical); reportBuilder.AddTable(dataView, true); } reportBuilder.AddColumn(columnStyle.MappingName, columnStyle.HeaderText, maxWidth, false, false, //dzs - do not autosize columns (ReportPrinting.HorizontalAlignment)columnStyle.Alignment); DataGridTextBoxColumn textCol = columnStyle as DataGridTextBoxColumn; if (textCol != null) { //Debug.WriteLine (textCol.Format); reportBuilder.CurrentColumn.FormatExpression = textCol.Format; } //float colWidth = reportBuilder.CurrentColumn.Width;//dzs //ReportDataColumn repColumn = reportBuilder.CurrentColumn;//dzs } } } //If this is still true than we have to load from the Table columns in the //dataView that the datagrid is using. // // IE there was NOT a valid DataGridTableStyle in the datagrid if (loadFromDataView) { reportBuilder.AddAllColumns(maxColumnSize, true, true); } reportBuilder.FinishLinearLayout(); }