/// <summary> /// Make ourselves a master row. This event is only expected to be received by the last master row. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void gv_DataBound(object sender, EventArgs e) { GridViewEx gv = this.Grid; _lastDetailRow._subtotalInfo = _subtotalInfo; _subtotalInfo = null; if (_markupComparer != null) { _markupComparer.Dispose(); _markupComparer = null; } // Tell sequence fields to not use page index while computing row sequence gv.Columns.Cast <DataControlField>() .OfType <SequenceField>().ToList().ForEach(p => p.UsePageIndex = false); }
/// <summary> /// If a detail row belonging to the next master is encountered, finalize our master status by /// creating _dictMasterCells. Unhook all grid events and hook them to the new master. /// </summary> /// <remarks> /// The function checks mark up of rows, if markup is not same this states that master is not same for both hence renders /// master row. Since this is a special row so we have to explicitly unhook to <see cref="GridViewEx" /> <c>RowDataBound</c> /// and <c>DataBound</c> events, then calling <c>InitializeSubTotals</c> for initializing master columns and after this the /// class again hooks to <c>GridViewEx</c> <c>RowDataBound</c> and <c>DataBound</c> events. If markups are same then the /// function perfoms row counts and summasion for all the child columns. /// </remarks> /// <param name="sender"></param> /// <param name="e"></param> private void gv_RowDataBound(object sender, GridViewRowEventArgs e) { if (!e.Row.Visible) { // Ignore return; } GridViewEx gv = this.Grid; GridViewExMasterRow row = e.Row as GridViewExMasterRow; if (row == null) { // Do nothing. This must be a normal row return; } // Sharad 26 Feb 2010: Checking this.RowIndex instead of this.DataItemIndex to avoid special situation bug of // subtotal and total // GL 11 June, 2010: Now checking row.DataItemIndex instead of row.RowIndex as this was resulting into // erronous sequencing in master-details reports when it was required to have new sequence for every master. if (row.DataItemIndex == this.RowIndex) { // First row of the master. Simply Initialize totals. We get here only for the very first master row. InitializeSubTotals(e.Row.DataItem, e.Row.RowIndex); return; } // e.Row is one of the detail rows or a new master row switch (e.Row.RowType) { case DataControlRowType.DataRow: if (_markupComparer == null) { _markupComparer = new ControlMarkupComparer(); } if (gv.MasterColumnIndexes.Any(p => !_markupComparer.MarkupSame( this.Cells[p], e.Row.Cells[p]))) { // First row of this master gv.RowDataBound -= gv_RowDataBound; gv.DataBound -= gv_DataBound; row._rowInfo._masterRowIndex = _rowInfo._masterRowIndex + 1; row._markupComparer = _markupComparer; row._lastDetailRow = row; row._rowInfo._indexWithinMaster = 0; row.InitializeSubTotals(row.DataItem, row.DataItemIndex); // first row of master is handing over the subtotals to the last row. // The last row will be responsible for displaying them. _lastDetailRow._subtotalInfo = _subtotalInfo; _subtotalInfo = null; gv.RowDataBound += row.gv_RowDataBound; gv.DataBound += row.gv_DataBound; } else { // Subsequent row of this master _lastDetailRow = row; row._rowInfo._indexWithinMaster = this._rowInfo._countRowsInMaster; ++_rowInfo._countRowsInMaster; _subtotalInfo.LastRowIndex = row.DataItemIndex; var query = gv.Columns.Cast <DataControlField>() .Select((p, i) => new { Column = p as INeedsSummaries, Index = i }) .Where(p => p.Column != null); foreach (var colInfo in query) { switch (colInfo.Column.DataSummaryCalculation) { case SummaryCalculationType.None: case SummaryCalculationType.DataSource: // No subtotals break; case SummaryCalculationType.ValueSummation: case SummaryCalculationType.ValueWeightedAverage: SummaryData data = _subtotalInfo.Subtotals[colInfo.Index]; for (int i = 0; i < colInfo.Column.DataFooterFields.Length; ++i) { object obj = DataBinder.Eval(e.Row.DataItem, colInfo.Column.DataFooterFields[i]); if (obj != DBNull.Value) { if (data.Values[i] == null) { data.Values[i] = Convert.ToDecimal(obj); } else { data.Values[i] += Convert.ToDecimal(obj); } ++data.RowCount; } } break; default: throw new NotImplementedException(); } } } break; } }