private void ApplyTopBottomFilter(Report rpt, Rows data) { if (data.Data.Count <= 0) // No data; nothing to do { return; } // Get the filter value and validate it FilterValue fv = this._FilterValues.Items[0]; double val = fv.Expression.EvaluateDouble(rpt, data.Data[0]); if (val <= 0) // if less than equal 0; then request results in no data { data.Data.Clear(); return; } // Calculate the row number of the affected item and do additional validation int ival; if (_FilterOperator == FilterOperatorEnum.TopN || _FilterOperator == FilterOperatorEnum.BottomN) { ival = (int)val; if (ival != val) { throw new Exception(string.Format(Strings.Filter_Error_TopNAndBottomNRequireInt, val)); } if (ival >= data.Data.Count) // includes all the data? { return; } ival--; // make zero based } else { if (val >= 100) // greater than 100% means all the data { return; } ival = (int)(data.Data.Count * (val / 100)); if (ival <= 0) // if less than equal 0; then request results in no data { data.Data.Clear(); return; } if (ival >= data.Data.Count) // make sure rounding hasn't forced us past 100% { return; } ival--; // make zero based } // Sort the data by the FilterExpression List <RowsSortExpression> sl = new List <RowsSortExpression>(); sl.Add(new RowsSortExpression(this._FilterExpression)); data.SortBy = sl; // update the sort by data.Sort(); // sort the data // reverse the order of the data for top so that data is in the beginning if (_FilterOperator == FilterOperatorEnum.TopN || _FilterOperator == FilterOperatorEnum.TopPercent) { data.Data.Reverse(); } List <Row> ar = data.Data; TypeCode tc = _FilterExpression.GetTypeCode(); object o = this._FilterExpression.Evaluate(rpt, data.Data[ival]); // adjust the ival based on duplicate values ival++; while (ival < ar.Count) { object n = this._FilterExpression.Evaluate(rpt, data.Data[ival]); if (ApplyCompare(tc, o, n) != 0) { break; } ival++; } if (ival < ar.Count) // if less than we need to remove the rest of the rows { ar.RemoveRange(ival, ar.Count - ival); } return; }