This is a migrated thread and some comments may be shown as answers.

Creating table programatically takes too much time

4 Answers 237 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Jasper
Top achievements
Rank 1
Jasper asked on 04 Oct 2010, 01:47 PM
Hi,

I'm creating a table completely programtically, creating all columns, rows and textboxes programatically and it works fine. But if I assign styles rules to the textboxes it needs a very long time render the report, depending on the number of objects. It seems that the rendering time increases exponentially.

4 Answers, 1 is accepted

Sort by
0
Jasper
Top achievements
Rank 1
answered on 04 Oct 2010, 03:27 PM
I found out that the StyleSheet.Add()/StyleSheet.AddRange() method is the problem. If I add one or more styles rules (with style selector) using Add()/AddRange() it takes a long time to render the report, also if the styles rules are not applied to any object of the report.
Strangely it does not have any serious performance impact if I add a descendant selector to the report.
0
Jasper
Top achievements
Rank 1
answered on 04 Oct 2010, 08:49 PM

I've created a simplified version to illustrate my approach.

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Text;
using Telerik.Reporting;
using Telerik.Reporting.Drawing;
  
namespace WindowsFormsApplication1
{
    /// <summary>
    /// Summary description for Report1.
    /// </summary>
    public partial class Report1 : Telerik.Reporting.Report
    {
        public Report1()
        {
            //
            // Required for telerik Reporting designer support
            //
            InitializeComponent();
        }
  
        private void Report1_ItemDataBinding(object sender, EventArgs e)
        {
            Unit globalRowHeight = new Unit(1d, UnitType.Cm);
            DataTable data = GetData();
            List<StyleRule> columnStyle = new List<StyleRule>();
  
            #region
  
            //Descendant style
            StyleRule defaultTextBoxStyle = new StyleRule();
            DescendantSelector descendantSelector = new DescendantSelector();
            descendantSelector.Selectors.AddRange(new ISelector[]
                {
                    new TypeSelector(typeof(Table)), 
                    new TypeSelector(typeof(TextBox))
                });
            defaultTextBoxStyle.Selectors.AddRange(new ISelector[] { descendantSelector });
            defaultTextBoxStyle.Style.BorderStyle.Default = BorderType.Solid;
            defaultTextBoxStyle.Style.BorderWidth.Default = new Unit(0.15d, UnitType.Mm);
            defaultTextBoxStyle.Style.Color = Color.Red;
            defaultTextBoxStyle.Style.Font.Bold = true;
            defaultTextBoxStyle.Style.Font.Name = "Tahoma";
            defaultTextBoxStyle.Style.TextAlign = HorizontalAlign.Left;
            defaultTextBoxStyle.Style.VerticalAlign = VerticalAlign.Middle;
  
            //Styles per col
            for (int i = 0; i < data.Columns.Count; i++)
            {
                StyleRule sr = new StyleRule();
                sr.Selectors.Add(new StyleSelector("columnStyle_" + i));
                sr.Style.BorderStyle.Default = BorderType.Solid;
                sr.Style.BorderWidth.Default = new Unit(0.15d, UnitType.Mm);
                sr.Style.Font.Name = "Tahoma";
                sr.Style.TextAlign = HorizontalAlign.Left;
                sr.Style.VerticalAlign = VerticalAlign.Middle;
                columnStyle.Add(sr);
            }
  
            //Styles for thead
            StyleRule headerStyle = new StyleRule();
            headerStyle.Selectors.Add(new StyleSelector("headerStyle"));
            headerStyle.Style.BorderStyle.Default = BorderType.Solid;
            headerStyle.Style.BorderWidth.Default = new Unit(0.15d, UnitType.Mm);
            headerStyle.Style.Font.Name = "Tahoma";
            headerStyle.Style.TextAlign = HorizontalAlign.Left;
            headerStyle.Style.VerticalAlign = VerticalAlign.Middle;
  
            #endregion
  
            //Add styles
            //This is slow
            StyleSheet.AddRange(columnStyle.ToArray());
  
            //This is slow too
            StyleSheet.Add(headerStyle);
  
            //This is fast
            //StyleSheet.AddRange(new StyleRule[] { defaultTextBoxStyle });
  
            Telerik.Reporting.Processing.Table processingTable = 
                (sender as Telerik.Reporting.Processing.Table);
            if (processingTable != null)
                processingTable.DataSource = data;
  
            //Clear Table
            table1.RowGroups.Clear();
            table1.ColumnGroups.Clear();
            table1.Body.Columns.Clear();
            table1.Body.Rows.Clear();
  
            TableGroup detailGroup = new TableGroup();
  
            for (int j = 0; j < data.Columns.Count; j++)
            {
                table1.Body.Columns.Add(new TableBodyColumn(new Unit(3.0d, UnitType.Cm)));
                //Create TextBoxes for table header
                Telerik.Reporting.TextBox headerTextBox = new Telerik.Reporting.TextBox
                {
                    StyleName = "headerStyle",
                    Value = data.Columns[j].ColumnName,
                    Size = new SizeU(new Unit(3.0d, UnitType.Cm), globalRowHeight)
  
                };
  
                //Add thead
                TableGroup tableGroup = new TableGroup {ReportItem = headerTextBox};
                table1.ColumnGroups.Add(tableGroup);
  
                //Create TextBoxes
                for (int i = 0; i < data.Rows.Count; i++)
                {
                    string styleSheet = "columnStyle_" + j;
                    Telerik.Reporting.TextBox textBox = new Telerik.Reporting.TextBox
                    {
                        StyleName = styleSheet,
                        Value = data.Rows[i][j].ToString(),
                        Size = new SizeU(new Unit(3.0d, UnitType.Cm), globalRowHeight)
                    };
                    table1.Body.SetCellContent(i, j, textBox);
  
                }
            }
  
            // ReSharper disable ForCanBeConvertedToForeach
            for (int i = 0; i < data.Rows.Count; i++)
            {
                table1.Body.Rows.Add(new TableBodyRow(globalRowHeight));
                detailGroup.ChildGroups.Add(new TableGroup());
            }
            // ReSharper restore ForCanBeConvertedToForeach
  
            table1.RowGroups.Add(detailGroup);
  
        }
  
        //Get data table from northwind db
        private static DataTable GetData()
        {
            DataSet ds = new DataSet();
            StringBuilder sb = new StringBuilder();
            sb.Append("Data Source=SQLSERVER;Initial Catalog=AdventureWorks;");
            sb.Append("Integrated Security = true;");
            StringBuilder query = new StringBuilder();
            query.Append("SELECT TOP 300 [Name], [ProductNumber], [StandardCost], ");
            query.Append("[ListPrice], [SellStartDate] FROM ");
            query.Append("[AdventureWorks].[Production].[Product]");
            using (SqlConnection con = new SqlConnection(sb.ToString()))
            {
                SqlDataAdapter adapter = new SqlDataAdapter();
                adapter.SelectCommand = new SqlCommand(query.ToString(), con);
                adapter.Fill(ds);
            }
            return ds.Tables[0];
        }
    }
}
0
Jasper
Top achievements
Rank 1
answered on 05 Oct 2010, 12:31 PM
Ok, I've written my own method to apply styles to an object. I simply iterate all style properties of a style rule and assign them one by one to the style properties of the respective object. This is incredibly faster than using style rules as recommended in the docs.
Hence it would be great if the setter of the style property could be made public in one of the upcoming releases of Telerik Reporting to combine ease of use and performance.


Kind Regards
0
Steve
Telerik team
answered on 07 Oct 2010, 12:47 PM
Hi Jasper,

We have a suspicion that the slowdown comes from the fact that you never invoke BeginInit() and EndInit(). This way all styles are re-added for every item, thus whenever you're making modifications to the definition styles you should invoke BeginInit() and EndInit() just like the Report Designer generates them in the InitializeComponent() method i.e.:

((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
//your stylerules adding code here
((System.ComponentModel.ISupportInitialize)(this)).EndInit();

Greetings,
Steve
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Tags
General Discussions
Asked by
Jasper
Top achievements
Rank 1
Answers by
Jasper
Top achievements
Rank 1
Steve
Telerik team
Share this question
or