Tuesday, January 8, 2013

Dynamically create ListView and thier templates at runtime

I have created a Composite control, which contains a listview to display a table of items. I am using a ListView in Asp.NET and define the templates in the code-behind.

using System;
using System.Web;
using System.Web.UI;

public partial class Report1 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
      {
    }

    protected override void CreateChildControls()
        {
            base.CreateChildControls();

            ListView view = new ListView();

        view.ID = "view";
            view.LayoutTemplate = new LayoutTemplate();
        view.GroupTemplate = new GroupTemplate();
            view.ItemTemplate = new ItemTemplate();

            view.DataSource = FibonacciSequence();    //assign List objects for custom design
            view.DataBind();

            pnl.Controls.Add(view);
        }

    public int Iterations { get; set; }

    private IEnumerable FibonacciSequence()
      {
            int i1 = 0;
            int i2 = 1;
            Iterations = 5;
            for (int i = 0; i < Iterations; i++)
            {
                yield return i1 + i2;
                int temp = i1 + i2;
                i1 = i2;
                i2 = temp;
            }
            yield break;
      }

    public class LayoutTemplate : ITemplate
      {
            public void InstantiateIn(Control container)
            {
                var div = new HtmlGenericControl("div") { ID = "groupPlaceholder" };
                container.Controls.Add(div);
            }
      }

    public class GroupTemplate : ITemplate
      {
            public void InstantiateIn(Control container)
            {
                var tbl1 = new HtmlGenericControl("table");
                tbl1.Attributes.Add("cellpadding", "0");
                tbl1.Attributes.Add("cellspacing", "0");
                tbl1.Attributes.Add("border", "0");
                tbl1.Attributes.Add("class", "tblBorder");
                tbl1.Attributes.Add("width", "100%");
                var tr1 = new HtmlGenericControl("tr");
                var td1 = new HtmlGenericControl("td");
                td1.Style.Add("padding", "5px");

                var tbl2 = new HtmlGenericControl("table");
                tbl2.Attributes.Add("cellpadding", "3px");
                tbl2.Attributes.Add("cellspacing", "0");
                tbl2.Attributes.Add("border", "0");
                tbl2.Attributes.Add("width", "100%");
                var tr2 = new HtmlGenericControl("tr") { ID = "itemPlaceholder" };

                tbl2.Controls.Add(tr2);
                td1.Controls.Add(tbl2);
                tr1.Controls.Add(td1);
                tbl1.Controls.Add(tr1);
                container.Controls.Add(tbl1);
            }
      }

        public class ItemTemplate : ITemplate
      {
            public void InstantiateIn(Control container)
            {
                var tr = new HtmlGenericControl("tr");
                tr.DataBinding += DataBinding;
                container.Controls.Add(tr);
            }

            public void DataBinding(object sender, EventArgs e)
            {
                var container = (HtmlGenericControl)sender;
                var dataItem = ((ListViewDataItem)container.NamingContainer).DataItem;

                container.Controls.Add( new Literal(){Text = dataItem.ToString() });

            //For custom design
            //container.Controls.Add( new Literal(){Text = GetValue(dataItem) });
            }

        protected string GetValue(object obj)
            {
            //parse object and do customized design

            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(obj.GetType());

                    string SVALUE, SNAME = string.Empty;

            foreach (PropertyDescriptor prop in properties)
                    {
                        if (prop.GetValue(obj) != null)
                        {
                            SVALUE = prop.GetValue(obj).ToString() ?? DBNull.Value.ToString();
                            SNAME = prop.Name;
                }
            }
        }
        }
}