Table of Contents

Introduction

Before I begin the introduction with dynamic control, I just want to specify how the control works on page. I got a doubt at the very beginning as to how the control persists on the page even after postback.

Well, here you go...

Whenever we run the page, it will be posted to the server, and the new instance of web page will get created every time and this means the page and the control on the page would get lost on every round trip. This has been overcome using the viewstate in ASP.NET which is a default properly of page, when we set viewstate of page to true, the viewstate property provides a dictionary object for retaining values between multiple roundtrips for the same page. It means before the page load ends, the control will be retained on the page and after the page load, we will be able to see the controls.

What is Dynamic Control

Yep, now let’s move to the term dynamic, the control which is not on design on the aspx page which framework parses, but the one we create by making the postback of the page by firing an event of another control. For example, create a textbox on button click.

However, it's better to understand that all controls on a page are actually dynamic at some stage of the page lifecycle.

The simple thing to remember here is that when we create a control on any event and want to retain them on any other action, then we should create them at every postback of the page.

Sample of Dynamic Control

As talked about earlier, we can create a control on any event. Here, we will use a listbox and on its SelectedIndexChanged, we will create a control.

Before we go far ahead, let’s see the DB design so that it will be clear as to what and how we move.

Please download and restore the DB in SQL Server.

Steps to restore can be found at this link.

Now, let me elaborate more. On Page load, I populate listbox. I am bind the MASTERDATATABLELIST table to Listbox where the DataTextField of the listbox is Table description (TABLENAMEDESC) and the Datavalue field is FILTERQUERY. (This field contains the SQL query select statement.)

Example

TABLENAMEDESC FILTERQUERY
ROLES SELECT Role "Role Description" , RoleID "Role Code" FROM AllRoles
public void BindListControl()
{
       string connectionStr = System.Configuration.ConfigurationManager.ConnectionStrings
				["ConnectionString"].ToString();
        SqlHelpe dataaccessHelper = new SqlHelpe(connectionStr);
         DataSet dataSet = new DataSet();
         string Mainquery = ViewState["MainQuery"].ToString();
        // View state is used here as per my requirement but recommended to avoid here
         dataSet = dataaccessHelper.ExecuteSelectQuery(Mainquery);
         lstTables.DataSource = dataSet.Tables[0];
         lstTables.DataTextField = "TABLENAMEDESC";
         lstTables.DataValueField = "FILTERQUERY";
         lstTables.DataBind();
}

Now let’s look at the dynamic control creation. We will be creating the control based on the fields in the select query and it will get changed as the query gets changed on selection. We will use the same control fields as filter parameters to retrieve the data.

Screen Design

Now let’s consider the select query on SelectedIndexChanged of listbox data “COUNTRY”.

As per the query, the place holder will be with the data table and each cell of the data table will contain Label and Textbox.

The code for creating dynamic textbox and label is as follows:

double rCount = Math.Ceiling(((double)columnCount / 4));
                int k = 0, rowsCount;
                rowsCount = (int)rCount;
                Table table = new Table();
                table.ID = "Table1";

                PlaceHolder1.Controls.Add(table);
                for (int i = 0; i < rowsCount; i++)
                {
                    int kC = 0;
                    TableRow row = new TableRow();
                    for (int j = 0; j < 4; j++)
                    {
                        TableCell cell = new TableCell();
                        Label lbl = new Label();
                        lbl.CssClass = "captions";
                        lbl.Width = 130;
                        lbl.ID = "Lable_" + i + "Col_" + j;
                        lbl.Text = StringArry[k, kC + 1].ToString();
                        TextBox tb = new TextBox();
                        tb.ID = StringArry[k, kC];
                        tb.Attributes.Add("EventHandler", "TextChanged");
                        // Add the control to the TableCell
                        cell.Controls.Add(lbl);
                        cell.Controls.Add(tb);
                        // Add the TableCell to the TableRow
                        row.Cells.Add(cell);
                        k = k + 1;
                        if (i * 4 + j == (columnCount - 1))
                        {
                            break;
                        }
                    }
                    // Add the TableRow to the Table
                    table.Rows.Add(row);
                }
            }

But now the question is, what if the query contains many fields in it. Well, we can show but we will lose the beauty in the page. I even want to cover how to bind dropdown on the page.

So here, if the query contains more than 8 fields, then we will see dropdown instead of textbox. So we will show for the below query:

Now, we will use the control(s) to add parameter and pass into where condition to get data on load button click (see below):

The code for dynamic dropdown creation is as follows:

double rCount = 2; Math.Ceiling(((double)columnCount / 3));
int k = 0, rowsCount;
rowsCount = (int)rCount;
Table table = new Table();
table.ID = "Table1";

PlaceHolder1.Controls.Add(table);

for (int i = 0; i < rowsCount; i++)
{
    int kC = 0;
    TableRow row = new TableRow();
    for (int j = 0; j < 3; j++)
    {
        TableCell cell = new TableCell();
        Label lbl = new Label();
        lbl.Width = 25;
 
        lbl.Text = "  ";
        DropDownList ddlist = new DropDownList();
        ddlist.Attributes.Add("EventHandler", "SelectedIndexChanged");
        ddlist.CssClass = "DropDownText";
        ddlist.ID = "ddl_" + k;
        ddlist.DataSource = dtStringArry;
        ddlist.DataTextField = dtStringArry.Columns["Col2"].ToString();
        ddlist.DataValueField = dtStringArry.Columns["Col1"].ToString();
        ddlist.DataBind();
        ddlist.Items.Insert(0, new ListItem("-SELECT-", "SELECT"));
        ddlist.SelectedIndex = 0;
        TextBox tb = new TextBox();
        tb.ID = "txt_" + k;
        tb.Attributes.Add("EventHandler", "TextChanged");
        cell.Controls.Add(ddlist);
        cell.Controls.Add(lbl);
        cell.Controls.Add(tb);
        row.Cells.Add(cell);
        k = k + 1;
        if (i * 3 + j == (columnCount - 1))
        {
            break;
        }
    }
    // Add the TableRow to the Table
    table.Rows.Add(row);
}

Reading the textbox control data:

TextBox tb = (TextBox)PlaceHolder1.FindControl(controlArrry[i, 0]);
 if (!String.IsNullOrEmpty(tb.Text))
 {
	string name1 = null;
	string strValue = tb.Text.ToString();
	name1 = tb.ID + " Like " + "'%" + tb.Text.Trim() + "%'" + " OR ";
	whereQuery += name1;
 }

Reading dropdown control data:

DropDownList ddl = (DropDownList)PlaceHolder1.FindControl("ddl_" + i);
if (!String.IsNullOrEmpty(ddl.SelectedValue) && ddl.SelectedValue != "SELECT")
{
	TextBox tb = (TextBox)PlaceHolder1.FindControl("txt_" + i);
	if (!String.IsNullOrEmpty(tb.Text))
	{
	 string name1 = null;
	 string strValue = tb.Text.ToString();
	 name1 = ddl.SelectedValue + " Like " + "'%" + tb.Text.Trim() + "%'" + " OR ";
	 whereQuery += name1;
	}
}

History

  • 26th June, 2011: Initial version
推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架
新浪微博粉丝精灵,刷粉丝、刷评论、刷转发、企业商家微博营销必备工具"