ASP.NET - to create grid dynamically with empty textboxes

Asked By anbu n on 13-Oct-11 10:37 PM

to create two fixed rows with dynamic columns [user will give some count for e.g. 4 is given by user, then 4 columns should be created with empty text boxes in grid]


Jitendra Faye replied to anbu n on 13-Oct-11 11:22 PM
The following code example demonstrates how to use the constructor to dynamically add a http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.templatefield.aspx field column to a http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.aspx control.

<%@ Page language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">

  // Create a template class to represent a dynamic template column.
  public class GridViewTemplate : ITemplate
  {
    private DataControlRowType templateType;
    private string columnName;

    public GridViewTemplate(DataControlRowType type, string colname)
    {
      templateType = type;
      columnName = colname;
    }

    public void InstantiateIn(System.Web.UI.Control container)
    {
      // Create the content for the different row types.
      switch(templateType)
      {
        case DataControlRowType.Header:
          // Create the controls to put in the header
          // section and set their properties.
          Literal lc = new Literal();
          lc.Text = "<b>" + columnName + "</b>";

          // Add the controls to the Controls collection
          // of the container.
          container.Controls.Add(lc);
          break;
        case DataControlRowType.DataRow:
          // Create the controls to put in a data row
          // section and set their properties.
          Label firstName = new Label();
          Label lastName = new Label();

          Literal spacer = new Literal();
          spacer.Text = " ";

          // To support data binding, register the event-handling methods
          // to perform the data binding. Each control needs its own event
          // handler.
          firstName.DataBinding += new EventHandler(this.FirstName_DataBinding);
          lastName.DataBinding += new EventHandler(this.LastName_DataBinding);

          // Add the controls to the Controls collection
          // of the container.
          container.Controls.Add(firstName);
          container.Controls.Add (spacer);
          container.Controls.Add(lastName);
          break;

        // Insert cases to create the content for the other 
        // row types, if desired.

        default:
          // Insert code to handle unexpected values.
          break; 
      }
    }

    private void FirstName_DataBinding(Object sender, EventArgs e)
    {
      // Get the Label control to bind the value. The Label control
      // is contained in the object that raised the DataBinding 
      // event (the sender parameter).
      Label l = (Label)sender;

      // Get the GridViewRow object that contains the Label control. 
      GridViewRow row = (GridViewRow)l.NamingContainer;

      // Get the field value from the GridViewRow object and 
      // assign it to the Text property of the Label control.
      l.Text = DataBinder.Eval(row.DataItem, "au_fname").ToString();
    }

    private void LastName_DataBinding(Object sender, EventArgs e)
    { 
      // Get the Label control to bind the value. The Label control
      // is contained in the object that raised the DataBinding 
      // event (the sender parameter).
      Label l = (Label)sender;

      // Get the GridViewRow object that contains the Label control.
      GridViewRow row = (GridViewRow)l.NamingContainer;

      // Get the field value from the GridViewRow object and 
      // assign it to the Text property of the Label control.
      l.Text = DataBinder.Eval(row.DataItem, "au_lname").ToString();
    }
  }

  void Page_Load(Object sender, EventArgs e)
  {

    // The field columns need to be created only when the page is
    // first loaded. 
    if (!IsPostBack)
    {
      // Dynamically create field columns to display the desired
      // fields from the data source. Create a TemplateField object 
      // to display an author's first and last name.
      TemplateField customField = new TemplateField();

      // Create the dynamic templates and assign them to 
      // the appropriate template property.
      customField.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Author Name");
      customField.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "Author Name");

      // Add the field column to the Columns collection of the
      // GridView control.
      AuthorsGridView.Columns.Add(customField);
    }

  }

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
  <head runat="server">
    <title>TemplateField Constructor Example</title>
</head>
<body>
    <form id="form1" runat="server">

      <h3>TemplateField Constructor Example</h3>

      <asp:gridview id="AuthorsGridView" 
        datasourceid="AuthorsSqlDataSource" 
        autogeneratecolumns="False"
        runat="server">                
      </asp:gridview>

      <!-- This example uses Microsoft SQL Server and connects -->
      <!-- to the Pubs sample database.                        -->
      <asp:sqldatasource id="AuthorsSqlDataSource"  
        selectcommand="SELECT [au_fname], [au_lname] FROM [authors]"
        connectionstring="server=localhost;database=pubs;integrated security=SSPI"
        runat="server">
      </asp:sqldatasource>

    </form>
  </body>
</html>

Try this code and let me know.
Web Star replied to anbu n on 13-Oct-11 11:53 PM
Here is complete code for that

Sample Image - DynamicColumnsWithTemplate.jpg

Introduction

This article describes about how to create template columns dynamically in a grid view.

Many times we have the requirement where we have to create columns dynamically. This article describes you about the dynamic loading of data using the DataTable as the datasource.

 

Let�s have a look at the code to understand better.

 

Create a gridview in the page,

  1. Drag and drop the GridView on to the page

Or

  1. Manually type GridView definition in the page.

 

<table border="0" cellpadding="0" cellspacing="0">

      <tr>

        <td>

          <strong>Dynamic Grid with Template Column</strong></td>

      </tr>

      <tr>

        <td>

          <asp:GridView ID="GrdDynamic" runat="server" AutoGenerateColumns="False">

          <Columns>

          </Columns>

          </asp:GridView>

        </td>

      </tr>

    </table>

 

With this we are done with creating a GridView in the page.

Let�s move on to the code-beside to understand the background history of the page.

Here I am describing about, how to create template columns.

 

//Iterate through the columns of the datatable to set the data bound field dynamically.

    foreach (DataColumn col in dt.Columns)

      {

      //Declare the bound field and allocate memory for the bound field.

      TemplateField bfield = new TemplateField();

 

      //Initalize the DataField value.

        bfield.HeaderTemplate = new GridViewTemplate(ListItemType.Header, col.ColumnName);

 

      //Initialize the HeaderText field value.

        bfield.ItemTemplate = new GridViewTemplate(ListItemType.Item, col.ColumnName);

 

      //Add the newly created bound field to the GridView.

        GrdDynamic.Columns.Add(bfield);

      }

 

    //Initialize the DataSource

      GrdDynamic.DataSource = dt;

 

    //Bind the datatable with the GridView.

      GrdDynamic.DataBind();

   

Let�s start dissecting right from the top,

 

  1. Create a DataTable which will hold the table definition and data for the GridView. This table is used as a DataSource for the GridView. 
    DataTable dt = new DataTable();
  2. Once the DataTable is created, let�s add 2 columns, ID & Name to the DataTable.
  3. The logic behind creating dynamic column starts by creating a TemplateField instance.
  4. Once the TemplateField is created, I am initializing the HeaderTemplate and ItemTemplate with the newly createdGridViewTemplate.We will come back to the GridViewTemplate again.
  5. Once the creation of the dynamic columns is completed, I am assigning the DataSource of the GridView and call the DataBind method to load the GridView with data dynamically.

 

Let�s come back to the interesting part of the template columns i.e class GridViewTemplate.

//A customized class for displaying the Template Column

public class GridViewTemplate : ITemplate

{

  //A variable to hold the type of ListItemType.

  ListItemType _templateType;

 

  //A variable to hold the column name.

  string _columnName;

 

  //Constructor where we define the template type and column name.

  public GridViewTemplate(ListItemType type, string colname)

    {

    //Stores the template type.

      _templateType = type;

 

    //Stores the column name.

      _columnName = colname;

    }

 

  void ITemplate.InstantiateIn(System.Web.UI.Control container)

    {

    switch (_templateType)

      {

      case ListItemType.Header:

        //Creates a new label control and add it to the container.

        Label lbl = new Label();      //Allocates the new label object.

          lbl.Text = _columnName;       //Assigns the name of the column in the lable.

          container.Controls.Add(lbl);    //Adds the newly created label control to the container.

        break;

 

      case ListItemType.Item:

        //Creates a new text box control and add it to the container.

        TextBox tb1 = new TextBox();              //Allocates the new text box object.

        tb1.DataBinding += new EventHandler(tb1_DataBinding);   //Attaches the data binding event.

          tb1.Columns = 4;                    //Creates a column with size 4.

          container.Controls.Add(tb1);              //Adds the newly created textbox to the container.

        break;

 

      case ListItemType.EditItem:

        //As, I am not using any EditItem, I didnot added any code here.

        break;

 

      case ListItemType.Footer:

        CheckBox chkColumn = new CheckBox();

          chkColumn.ID = "Chk" + _columnName;

          container.Controls.Add(chkColumn);

        break;

      }

    }

 

  /// <summary>

  /// This is the event, which will be raised when the binding happens.

  /// </summary>

  /// <param name="sender"></param>

  /// <param name="e"></param>

  void tb1_DataBinding(object sender, EventArgs e)

    {

    TextBox txtdata = (TextBox)sender;

    GridViewRow container = (GridViewRow)txtdata.NamingContainer;

    object dataValue = DataBinder.Eval(container.DataItem, _columnName);

    if (dataValue != DBNull.Value)

      {

        txtdata.Text = dataValue.ToString();

      }

    }

}

 

Any class that should be used as a template should be inherited from the ITemplate class.

ITemplate defines the behavior for populating a templated ASP.NET server control with child controls. The child controls represent the inline templates defined on the page.

 

One of the interesting method in the ITemplate class is InstantiateIn(Control Container),which defines the Control object that child controls and templates belong to. These child controls are in turn defined within an inline template.

 

In the InstanceIn method, based on the _templateType selected, I am creating the necessary controls.

 

That�s all your dynamic GridView is ready. I hope this information would be helpful.

 

There is another interesting scenario, I would like to bring forward. i.e let�s assume that we have added a button control to the page. Upon user clicking on the button control, the page gets post back. Once the page postback, and if we don�t create the template column again upon post back, the controls would disappear. This is one of the drawbacks of this approach.

 

Enjoy programming

TSN ... replied to anbu n on 14-Oct-11 12:19 AM
hi..
try the following..


TemplateField objTf = new TemplateField();
 objTf
.HeaderText ="column name";
 objTf
.ItemTemplate = new Gridviewtemplate();
 
GridView1.Columns.Add(objTf
);

and write a class as below

public class Gridviewtemplate : ITemplate
{
   
public Gridviewtemplate()
   
{
 
   
}
 
   
void ITemplate.InstantiateIn(Control container)
   
{
       
TextBox objTb = new TextBox();          //Allocates the newtext box object.
        objTb
.Columns = 4;                            //Creates a column with size 4.
        container
.Controls.Add(objTb);
   
}
}
hope this helps you....
smr replied to anbu n on 14-Oct-11 01:15 AM
HI


your life would be much easier if you used a DataGrid... if you absolutely must use TextBoxes though... in code, create an array of TextBoxes and populate it not unlike this...

    

for (int x = 0; x < DesiredNumberOfTextBoxes; x++)
     {
       textBoxes[x] = new TextBox();
       textBoxes[x].Location = //Set desired location
       textBoxes[x].Size = //Set desired size
       Controls.Add(textBoxes[x]); //Add TextBox to parent container
     }

Only a bit bigger and probably using a two dimensional array and more advanced math for positioning.


refer
http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/7b7e8b5f-7904-4c73-b438-f697e6e152bf
http://www.aspmessageboard.com/showthread.php?t=233504
smr replied to anbu n on 14-Oct-11 01:15 AM
HI


your life would be much easier if you used a DataGrid... if you absolutely must use TextBoxes though... in code, create an array of TextBoxes and populate it not unlike this...

    

for (int x = 0; x < DesiredNumberOfTextBoxes; x++)
     {
       textBoxes[x] = new TextBox();
       textBoxes[x].Location = //Set desired location
       textBoxes[x].Size = //Set desired size
       Controls.Add(textBoxes[x]); //Add TextBox to parent container
     }

Only a bit bigger and probably using a two dimensional array and more advanced math for positioning.


refer
http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/7b7e8b5f-7904-4c73-b438-f697e6e152bf
http://www.aspmessageboard.com/showthread.php?t=233504
anbu n replied to TSN ... on 14-Oct-11 03:34 AM
this below method is not getting called, 


void
ITemplate.InstantiateIn(Control container)
   
{
       
TextBox objTb = new TextBox();          //Allocates the newtext box object.
        objTb
.Columns = 4;                            //Creates a column with size 4.
        container
.Controls.Add(objTb);
   
}
anbu n replied to Jitendra Faye on 14-Oct-11 03:35 AM

this below method is not getting called, 


 public void InstantiateIn(System.Web.UI.Control container)
    {
      // Create the content for the different row types.
      switch(templateType)
      {
        case DataControlRowType.Header:
          // Create the controls to put in the header
          // section and set their properties.
          Literal lc = new Literal();
          lc.Text = "<b>" + columnName + "</b>";

          // Add the controls to the Controls collection
          // of the container.
          container.Controls.Add(lc);
          break;
        case DataControlRowType.DataRow:
          // Create the controls to put in a data row
          // section and set their properties.
          Label firstName = new Label();
          Label lastName = new Label();

          Literal spacer = new Literal();
          spacer.Text = " ";

          // To support data binding, register the event-handling methods
          // to perform the data binding. Each control needs its own event
          // handler.
          firstName.DataBinding += new EventHandler(this.FirstName_DataBinding);
          lastName.DataBinding += new EventHandler(this.LastName_DataBinding);

          // Add the controls to the Controls collection
          // of the container.
          container.Controls.Add(firstName);
          container.Controls.Add (spacer);
          container.Controls.Add(lastName);
          break;

        // Insert cases to create the content for the other 
        // row types, if desired.

        default:
          // Insert code to handle unexpected values.
          break; 
      }
    }
anbu n replied to Jitendra Faye on 14-Oct-11 03:37 AM

this below method is not getting called, 


 public void InstantiateIn(System.Web.UI.Control container)
    {
      // Create the content for the different row types.
      switch(templateType)
      {
        case DataControlRowType.Header:
          // Create the controls to put in the header
          // section and set their properties.
          Literal lc = new Literal();
          lc.Text = "<b>" + columnName + "</b>";

          // Add the controls to the Controls collection
          // of the container.
          container.Controls.Add(lc);
          break;
        case DataControlRowType.DataRow:
          // Create the controls to put in a data row
          // section and set their properties.
          Label firstName = new Label();
          Label lastName = new Label();

          Literal spacer = new Literal();
          spacer.Text = " ";

          // To support data binding, register the event-handling methods
          // to perform the data binding. Each control needs its own event
          // handler.
          firstName.DataBinding += new EventHandler(this.FirstName_DataBinding);
          lastName.DataBinding += new EventHandler(this.LastName_DataBinding);

          // Add the controls to the Controls collection
          // of the container.
          container.Controls.Add(firstName);
          container.Controls.Add (spacer);
          container.Controls.Add(lastName);
          break;

        // Insert cases to create the content for the other 
        // row types, if desired.

        default:
          // Insert code to handle unexpected values.
          break; 
      }
    }
anbu n replied to Web Star on 14-Oct-11 03:39 AM

the below method is not getting called,



void ITemplate.InstantiateIn(System.Web.UI.Control container)

    {

  switch (_templateType)

    {

    case ListItemType.Header:

    //Creates a new label control and add it to the container.

    Label lbl = new Label();    //Allocates the new label object.

      lbl.Text = _columnName;     //Assigns the name of the column in the lable.

      container.Controls.Add(lbl);  //Adds the newly created label control to the container.

    break;

 

    case ListItemType.Item:

    //Creates a new text box control and add it to the container.

    TextBox tb1 = new TextBox();        //Allocates the new text box object.

    tb1.DataBinding += new EventHandler(tb1_DataBinding);   //Attaches the data binding event.

      tb1.Columns = 4;          //Creates a column with size 4.

      container.Controls.Add(tb1);        //Adds the newly created textbox to the container.

    break;

 

    case ListItemType.EditItem:

    //As, I am not using any EditItem, I didnot added any code here.

    break;

 

    case ListItemType.Footer:

    CheckBox chkColumn = new CheckBox();

      chkColumn.ID = "Chk" + _columnName;

      container.Controls.Add(chkColumn);

    break;

    }

    }

dipa ahuja replied to anbu n on 14-Oct-11 03:59 AM
If you have to just create textboxes with fixed no. then better to create dynamic textbox control with table not Gridview

Untitled document
void AddControls()
{
   Table tb = new Table();
   tb.ID = "Table1";
 
   for (int i = 0; i < 3; i++)
   {
     Label lbl = new Label();
     lbl.Text = "s" + i.ToString() + i.ToString();
 
     TableRow r = new TableRow();
 
     TextBox txt = new TextBox();
     txt.ID = "chk" + i.ToString();
     //adding lable
     TableCell c1 = new TableCell();
     c1.Controls.Add(lbl);
     r.Cells.Add(c1);
 
     //adding textbox
     TableCell c2 = new TableCell();
     c2.Controls.Add(txt);
     r.Cells.Add(c2);
 
     tb.Rows.Add(r);
   }
   Page.Form.Controls.Add(tb);
}

Now call this on the page_load