 Again with some Telerik Reporting goodies. If you observe my previous post, you would notice that Telerik Reporting is not only my favorite reporting tool but also one of my favorite .NET libraries to work with. This time I write to unveil one additional solution that may not be consider one of the most intuitive or yet most proximate.

Telerik Reporting provides the ability to implement conditional formation in a global level but also in a singular level at a report item. In writing several reports, I have had to introduce numerous formatting rules. Very seldom one rule would apply for the whole report.

Furthermore, consider the following equations for the rate of return, or a weighted average calculation based

`   1: = SUM(Fields.DollarAmount * (Fields.RateOfReturn / 100)) / SUM(Fields.DollarAmount)`
`   2: =SUM( `
`   3: IIF(Fields.MetricType=1,`
`   4: Fields.ProductionData.DataAnalysis.ProductionMetrics.FirstMilk1 * 2.272,`
`   5: Fields.ProductionData.DataAnalysis.ProductionMetrics.FirstMilk1)`
`   6: * Fields.ProductionData.DataAnalysis.ProductionMetrics.CowNumbers`
`   7: )`
`   8: / `
`   9: SUM(IIF(Fields.ProductionData.DataAnalysis.ProductionMetrics.FirstMilk1>0,`
`  10:  Fields.ProductionData.DataAnalysis.ProductionMetrics.CowNumbers,0)`
`  11: )`

Since the value of this expression is resolved at run time. We would have to insert this expression as part of our conditional formatting in order to customize our report. Nonetheless, based on the size of our report this task could become tedious and time consuming. In addition, imagine numerous column in our report with numerous field to evaluate.

### The Solution

The best way to overcome performing this task is to access the report when elements have already been bound. Thus, we could determine if we either want to apply a custom color based on value rather than field. The way the we can accomplish this in a table and in a report object vary.

#### In a Table Object

The following Example hides the zero Values from the Report

`   1: // In the Report Constructor or Desing (Define Item Data Bound Event)`
`   2: public Report()`
`   3: {`
`   4:     InitializeComponent();`
`   5:     this.crosstabTable.ItemDataBound += crosstabTableItemDataBound`
`   6: }`
`   1: void crosstabTableItemDataBound(object sender, EventArgs e)`
`   2: {`
`   3:     Telerik.Reporting.Processing.Table table = `
`   4:                     (Telerik.Reporting.Processing.Table)sender;`
`   5:  `
`   6:     var elements = Telerik.Reporting.Processing.ElementTreeHelper.GetChildElements(table)`
`   7:                .Where(k => k.GetType() == typeof(Telerik.Reporting.Processing.TextBox))`
`   8:                .Select(l => l)`
`   9:                 .Where(con => {`
`  10:                     Telerik.Reporting.Processing.TextBox txtbox = con as Telerik.Reporting.Processing.TextBox;`
`  11:                     string value = txtbox.Text;`
`  12:                     return (value == "NaN") || (value == "0.00") || (value == "0") || (value == "0.0") || value.IndexOf("0.00") != -1;`
`  13:                     `
`  14:                 }).Select(m => m);`
`  15:  `
`  16:             foreach (Telerik.Reporting.Processing.TextBox tbox in elements)`
`  17:             {`
`  18:                 tbox.Value = "";`
`  19:             }`
`  20: }`

#### In a Report Object

Since the Textbox elements that need to be customized are not a direct children of the Report Item; we would have to extract all this elements in a recursive fashion from all the children contain within a report item.

`   1: // Obtain Report TextBoxes Recursivelly`
`   2: private List<Telerik.Reporting.Processing.TextBox> GetTboxesRecursive(Telerik.Reporting.Processing.LayoutElement parent)`
`   3: {`
`   4:     List<Telerik.Reporting.Processing.TextBox> tboxes = new List<Telerik.Reporting.Processing.TextBox>();`
`   5:  `
`   6:     var element = Telerik.Reporting.Processing.ElementTreeHelper.GetChildElements(parent);`
`   7:     foreach (var item in element)`
`   8:     {`
`   9:         if (item.GetType() == typeof(Telerik.Reporting.Processing.TextBox))`
`  10:         {`
`  11:             tboxes.Add(item as Telerik.Reporting.Processing.TextBox);`
`  12:         }`
`  13:         else`
`  14:         {`
`  15:             tboxes.AddRange(GetTboxesRecursive(item));`
`  16:         }`
`  17:     }`
`  18:     return tboxes;`
`  19:     `
`  20: }`

We now are ready to apply the changes to our bounded elements

`   1: void Report_ItemDataBound(object sender, EventArgs e)`
`   2: {`
`   3:     Telerik.Reporting.Processing.Report report = (Telerik.Reporting.Processing.Report)sender;`
`   4:  `
`   5:     var elements = GetTboxesRecursive(report).Select(l => l).Where(con =>`
`   6:     {`
`   7:  `
`   8:         string value = con.Text;`
`   9:         return (value == "NaN") || (value == "0.00") || (value == "0") || (value == "0.0") || value.IndexOf("0.00") != -1;`
`  10:     `
`  11:     }).Select(k => k);`
`  12:         `
`  13:  `
`  14:     foreach (Telerik.Reporting.Processing.TextBox tbox in elements)`
`  15:     {`
`  16:         //let us display the elements in red this time..`
`  17:         tbox.Style.Color = Color.Red;`
`  18:     }`
`  19: }` 