C# .NET - Dynamically Creating TemplateFields for GridView in C#

Asked By Jarrod Krige on 23-Jul-10 10:09 AM

Hello, please help me. I'm dynamically creating TemplateFields for GridView depending on the table to be displayed.

So, I've created a GridView with no fields in ASPX, bound to a SQLDataSource:


<asp:GridView ID="gridData" runat="server" HorizontalAlign="Center" 
      Font-Names="Arial" Font-Size="7pt" Width="798px" 
      DataSourceID="sqlDataSource" AutoGenerateColumns="False" 
    AllowPaging="True" AutoGenerateDeleteButton="True"
    AutoGenerateEditButton="True" EmptyDataText="> > There is no data to display < <">
      <HeaderStyle Font-Bold="True" Font-Names="Arial" Font-Size="9pt" 
        ForeColor="White" BackColor="#999999" />
        <AlternatingRowStyle HorizontalAlign="Center" BackColor="#E6E6E6" />
      <EditRowStyle HorizontalAlign="Center" BackColor="#FFFF99" />
      <EmptyDataRowStyle HorizontalAlign="Center" />
      <FooterStyle HorizontalAlign="Center" />
      <PagerSettings Mode="NextPreviousFirstLast" />
      <PagerStyle Font-Names="Arial" Font-Size="9pt" ForeColor="White" 
        HorizontalAlign="Center" BackColor="#999999" Font-Bold="True" />
      <RowStyle HorizontalAlign="Center" />
    </asp:GridView>
    <br />
  <asp:ImageButton ID="btnInsert" runat="server" />
     
  <asp:SqlDataSource
    id="sqlDataSource"
    runat="server"
    OnInserted ="On_Inserted" OnUpdated="On_Updated" 
    onupdating="sqlDataSource_Updating" OnInserting="sqlDataSource_Inserting">
  </asp:SqlDataSource>

 

And then I've created a new class implementing ITemplate.....


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
  
public class GridViewTemplate : ITemplate
{
  private DataControlRowType templateType;
  private string columnNameFriendly;
  private string columnNameData;
  private Control control;
  
  public GridViewTemplate(DataControlRowType type, string colNameFr, string colNameDt, Control con)
  {
    templateType = type;
    columnNameFriendly = colNameFr;
    columnNameData = colNameDt;
    control = con;
  }
  
  public void InstantiateIn(System.Web.UI.Control container)
  {
    switch (templateType)
    {
      case DataControlRowType.Header:
        {
          Literal lc = new Literal();
          lc.Text = columnNameFriendly;
          container.Controls.Add(lc);
          break;
        }
      case DataControlRowType.DataRow:
        {
          Control field = control;
          field.DataBinding += new EventHandler(this.field_DataBinding);
          container.Controls.Add(field);
          break;
        }
    }
  }
  
  private void field_DataBinding(Object sender, EventArgs e)
  {
    Control c = (Control)sender;
    GridViewRow row = (GridViewRow)c.NamingContainer;
    if (sender.GetType() == typeof(Label))
    {
      (c as Label).Text = DataBinder.Eval(row.DataItem, columnNameData).ToString();
      (c as Label).Font.Size = 7;
      (c as Label).Font.Name = "Arial";
    }
    else if (sender.GetType() == typeof(TextBox))
    {
      (c as TextBox).Text = DataBinder.Eval(row.DataItem, columnNameData).ToString();
      (c as TextBox).Font.Size = 7;
      (c as TextBox).Font.Name = "Arial";
    }
    else if (sender.GetType() == typeof(DropDownList))
    {
      (c as DropDownList).SelectedValue = DataBinder.Eval(row.DataItem, columnNameData).ToString();
      (c as DropDownList).Font.Size = 7;
      (c as DropDownList).Font.Name = "Arial";
    }
    else if (sender.GetType() == typeof(CheckBox))
    {
      (c as CheckBox).Checked = (bool)DataBinder.Eval(row.DataItem, columnNameData);
    }
  }
}

 

And then, the fields of GridView change depending on the Table I want to view or edit:

private void DrawFieldsAndSetQueries()
  {
    switch (Request.QueryString[0])
    {
      case "E"://"Company":
        {
          sqlDataSource.SelectCommand = "SELECT * FROM Company";
          sqlDataSource.UpdateCommand = "updateCompany";
          sqlDataSource.DeleteCommand = "deleteCompany";
          sqlDataSource.SelectCommandType = SqlDataSourceCommandType.Text;
          sqlDataSource.UpdateCommandType = SqlDataSourceCommandType.StoredProcedure;
          sqlDataSource.DeleteCommandType = SqlDataSourceCommandType.StoredProcedure;
          TemplateField tf1 = new TemplateField();
          tf1.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "Email", "Email", new Label());
          tf1.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Email", "Email", new Label());
          //tf1.EditItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Email", "Email", new TextBox()); //PRIMARY KEY
          TemplateField tf2 = new TemplateField();
          tf2.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "Name", "CompanyName", new Label());
          tf2.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Name", "CompanyName", new Label());
          tf2.EditItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Name", "CompanyName", new TextBox());
          TemplateField tf3 = new TemplateField();
          tf3.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "Telephone", "Telephone", new Label());
          tf3.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Telephone", "Telephone", new Label());
          tf3.EditItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Telephone", "Telephone", new TextBox());
          TemplateField tf4 = new TemplateField();
          tf4.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "Fax", "Fax", new Label());
          tf4.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Fax", "Fax", new Label());
          tf4.EditItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Fax", "Fax", new TextBox());
          gridData.Columns.Add(tf1);
          gridData.Columns.Add(tf2);
          gridData.Columns.Add(tf3);
          gridData.Columns.Add(tf4);
          break;
        }
      case "F"://"SystemUser":
        {
          sqlDataSource.SelectCommand = "SELECT DISTINCT SystemUser.Email, SystemUser.UserName, SystemUser.Password, SystemUser.Enabled, SystemUser.EmailOnProblems, SystemUser.Permission, Company.CompanyName, Department.DepartmentName FROM SystemUser INNER JOIN Company ON SystemUser.CompanyEmail = Company.Email INNER JOIN Department ON SystemUser.DepartmentID = Department.DepartmentID";
          sqlDataSource.UpdateCommand = "updateSystemUser";
          sqlDataSource.DeleteCommand = "deleteSystemUser";
          sqlDataSource.SelectCommandType = SqlDataSourceCommandType.Text;
          sqlDataSource.UpdateCommandType = SqlDataSourceCommandType.StoredProcedure;
          sqlDataSource.DeleteCommandType = SqlDataSourceCommandType.StoredProcedure;
          TemplateField tf1 = new TemplateField();
          tf1.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "Email", "Email", new Label());
          tf1.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Email", "Email", new Label());
          //tf1.EditItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Email", "Email", new TextBox()); //PRIMARY KEY
          TemplateField tf2 = new TemplateField();
          tf2.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "Name", "UserName", new Label());
          tf2.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Name", "UserName", new Label());
          tf2.EditItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Name", "UserName", new TextBox());
          TemplateField tf3 = new TemplateField();
          tf3.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "Enabled", "Enabled", new Label());
          tf3.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Enabled", "Enabled", new Label());
          tf3.EditItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Enabled", "Enabled", new CheckBox());
          TemplateField tf4 = new TemplateField();
          tf4.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "Emailed", "EmailOnProblems", new Label());
          tf4.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Emailed", "EmailOnProblems", new Label());
          tf4.EditItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Emailed", "EmailOnProblems", new CheckBox());
          TemplateField tf5 = new TemplateField();
          tf5.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "Administrator", "Permission", new Label());
          tf5.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Administrator", "Permission", new Label());
          tf5.EditItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Administrator", "Permission", new CheckBox());
          TemplateField tf6 = new TemplateField();
          tf6.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "Company", "CompanyName", new Label());
          tf6.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Company", "CompanyName", new Label());
          DropDownList ddlCompany = new DropDownList();
          SqlCommand sqlCom = new SqlCommand("SELECT DISTINCT CompanyName FROM Company", sqlCon);
          sqlCon.Open();
          SqlDataReader sqlRd = sqlCom.ExecuteReader();
          while (sqlRd.Read())
          {
            ddlCompany.Items.Add(sqlRd[0].ToString());
          }
          sqlRd.Close();
          sqlCon.Close();
          tf6.EditItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Company", "CompanyName", ddlCompany);
          TemplateField tf7 = new TemplateField();
          tf7.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "Department", "DepartmentName", new Label());
          tf7.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Department", "DepartmentName", new Label());
          DropDownList ddlDepartment = new DropDownList();
          ddlCompany.Items.Add("");
          SqlCommand sqlComD = new SqlCommand("SELECT DISTINCT DepartmentName FROM Department", sqlCon);
          sqlCon.Open();
          SqlDataReader sqlRdD = sqlComD.ExecuteReader();
          while (sqlRdD.Read())
          {
            ddlDepartment.Items.Add(sqlRdD[0].ToString());
          }
          sqlRdD.Close();
          sqlCon.Close();
          tf7.EditItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Department", "DepartmentName", ddlDepartment);
          gridData.Columns.Add(tf1);
          gridData.Columns.Add(tf2);
          gridData.Columns.Add(tf3);
          gridData.Columns.Add(tf4);
          gridData.Columns.Add(tf5);
          gridData.Columns.Add(tf6);
          gridData.Columns.Add(tf7);
          break;
        }
      case "G"://"Customer":
        {
          sqlDataSource.SelectCommand = "SELECT DISTINCT Customer.Email, Customer.CustomerName, Customer.Telephone, Customer.Fax, Company.CompanyName FROM Customer LEFT OUTER JOIN Company ON Customer.CompanyEmail = Company.Email";
          sqlDataSource.UpdateCommand = "updateCustomer";
          sqlDataSource.DeleteCommand = "deleteCustomer";
          sqlDataSource.SelectCommandType = SqlDataSourceCommandType.Text;
          sqlDataSource.UpdateCommandType = SqlDataSourceCommandType.StoredProcedure;
          sqlDataSource.DeleteCommandType = SqlDataSourceCommandType.StoredProcedure;
          TemplateField tf1 = new TemplateField();
          tf1.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "Email", "Email", new Label());
          tf1.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Email", "Email", new Label());
          //tf1.EditItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Email", "Email", new TextBox()); //PRIMARY KEY
          TemplateField tf2 = new TemplateField();
          tf2.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "Name", "CustomerName", new Label());
          tf2.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Name", "CustomerName", new Label());
          tf2.EditItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Name", "CustomerName", new TextBox());
          TemplateField tf3 = new TemplateField();
          tf3.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "Telephone", "Telephone", new Label());
          tf3.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Telephone", "Telephone", new Label());
          tf3.EditItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Telephone", "Telephone", new TextBox());
          TemplateField tf4 = new TemplateField();
          tf4.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "Fax", "Fax", new Label());
          tf4.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Fax", "Fax", new Label());
          tf4.EditItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Fax", "Fax", new TextBox());
          TemplateField tf5 = new TemplateField();
          tf5.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "Company", "CompanyName", new Label());
          tf5.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Company", "CompanyName", new Label());
          DropDownList ddl = new DropDownList();
          SqlCommand sqlCom = new SqlCommand("SELECT DISTINCT CompanyName FROM Company", sqlCon);
          sqlCon.Open();
          SqlDataReader sqlRd = sqlCom.ExecuteReader();
          while (sqlRd.Read())
          {
            ddl.Items.Add(sqlRd[0].ToString());
          }
          sqlRd.Close();
          sqlCon.Close();
          tf5.EditItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Company", "CompanyName", ddl);
          gridData.Columns.Add(tf1);
          gridData.Columns.Add(tf2);
          gridData.Columns.Add(tf3);
          gridData.Columns.Add(tf4);
          gridData.Columns.Add(tf5);
          break;
        }
      case "H"://"ProblemCategory":
        {
          break;
        }
      case "I"://"Problem":
        {
          break;
        }
      case "J"://"Priority":
        {
          break;
        }
      case "K"://"Department":
        {
          break;
        }
      case "L"://"Costing":
        {
          break;
        }
    }
    gridData.DataBind();
  }


THE ONLY PROBLEM IS.....

Only the last row displays like shown below:


Or if I click edit on the last row: then the above rows display, except the Email label:



I thought at first that there may be a problem with my labels but i parsed control type TextBox instead and that then displayed the last row as textboxes instead of labels but the other rows are still hidden (not null i don't think, just missing.)



Am I missing a if(!Page.IsPostBack) or something stupid. This is driving me nuts, please help! Any ideas would be appreciated.

Fusion IT replied to Jarrod Krige on 25-Jul-10 09:57 PM

Hi Jarrod,

I have just tweaked your code as follow.
1) I have used two separate eventhandlers for Edit and item templates, and commented out

field_DataBinding routine.// This should display all your datarows in result set

2) I uncommented following line in your DrawFieldsAndSetQueries() routine.

 

tf1.EditItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "Email", "Email", new TextBox()); //PRIMARY KEY - This should display textbox for Email field when in edit mode


 

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

{

switch (templateType)

{

case DataControlRowType.Header:

{

  Literal lc = new Literal();

  lc.Text = columnNameFriendly;

  container.Controls.Add(lc);

  break;

}

case DataControlRowType.DataRow:

{

Control field = control;

//field.DataBinding += new EventHandler(this.field_DataBinding);

//container.Controls.Add(field);

 

//break;

 

  if (field.GetType() == typeof(Label))

  {

    Label lbl = new Label();

    lbl.DataBinding += new EventHandler(this.lbl_DataBind);

    container.Controls.Add(lbl);

  }

  else if (field.GetType() == typeof(TextBox))

  {

    TextBox txt = new TextBox();

    txt.DataBinding += new EventHandler(this.txt_DataBind);

    container.Controls.Add(txt);

  }


  break;

}

}

}

private void txt_DataBind(Object sender, EventArgs e)

{

  TextBox txt = (TextBox)sender;

  GridViewRow row = (GridViewRow)txt.NamingContainer;

  txt.Text = DataBinder.Eval(row.DataItem, columnNameData).ToString();

}

private void lbl_DataBind(Object sender, EventArgs e)

{

  Label lbl = (Label)sender;

  GridViewRow row = (GridViewRow)lbl.NamingContainer;

  lbl.Text = DataBinder.Eval(row.DataItem, columnNameData).ToString();

}

I hope this helps. Please let me know if you find anything confusing.
Good luck.

Jarrod Krige replied to Fusion IT on 26-Jul-10 03:49 AM
THANKS, THAT WORKS GREAT!! Appreciate your assistance!

I've added the events for ddls and cbxs:


public class GridViewTemplate : ITemplate
{
  private DataControlRowType templateType;
  private string columnNameFriendly;
  private string columnNameData;
  private Control control;
  
  public GridViewTemplate(DataControlRowType type, string colNameFr, string colNameDt, Control con)
  {
    templateType = type;
    columnNameFriendly = colNameFr;
    columnNameData = colNameDt;
    control = con;
  }
  
  public void InstantiateIn(System.Web.UI.Control container)
  {
    switch (templateType)
    {
      case DataControlRowType.Header:
        {
          Literal lc = new Literal();
          lc.Text = columnNameFriendly;
          container.Controls.Add(lc);
          break;
        }
      case DataControlRowType.DataRow:
        {
          Control field = control;
          if (field.GetType() == typeof(Label))
          {
            Label lbl = new Label();
            lbl.DataBinding += new EventHandler(this.lbl_DataBind);
            container.Controls.Add(lbl);
          }
          else if (field.GetType() == typeof(TextBox))
          {
            TextBox txt = new TextBox();
            txt.DataBinding += new EventHandler(this.txt_DataBind);
            container.Controls.Add(txt);
          }
          else if (field.GetType() == typeof(DropDownList))
          {
            DropDownList ddl = (DropDownList)field;
            ddl.DataBinding += new EventHandler(this.ddl_DataBind);
            container.Controls.Add(ddl);
          }
          else if (field.GetType() == typeof(CheckBox))
          {
            CheckBox cbx = new CheckBox();
            cbx.DataBinding += new EventHandler(this.cbx_DataBind);
            container.Controls.Add(cbx);
          }
          break
        }
    }
  }
  
  private void txt_DataBind(Object sender, EventArgs e)
  {
  
    TextBox txt = (TextBox)sender;
    GridViewRow row = (GridViewRow)txt.NamingContainer;
    txt.Text = DataBinder.Eval(row.DataItem, columnNameData).ToString();
    txt.Font.Size = 7;
    txt.Font.Name = "Arial";
  }
  
  private void lbl_DataBind(Object sender, EventArgs e)
  {
    Label lbl = (Label)sender;
    GridViewRow row = (GridViewRow)lbl.NamingContainer;
    lbl.Text = DataBinder.Eval(row.DataItem, columnNameData).ToString();
    lbl.Font.Size = 7;
    lbl.Font.Name = "Arial";
  }
  
  private void ddl_DataBind(Object sender, EventArgs e)
  {
    DropDownList ddl = (DropDownList)sender;
    GridViewRow row = (GridViewRow)ddl.NamingContainer;
    ddl.SelectedValue = DataBinder.Eval(row.DataItem, columnNameData).ToString();
    ddl.Font.Size = 7;
    ddl.Font.Name = "Arial";
  }
  
  private void cbx_DataBind(Object sender, EventArgs e)
  {
    CheckBox cbx = (CheckBox)sender;
    GridViewRow row = (GridViewRow)cbx.NamingContainer;
    cbx.Checked = (bool)DataBinder.Eval(row.DataItem, columnNameData);
  }
}
Fusion IT replied to Jarrod Krige on 26-Jul-10 07:08 PM
I am glad to know that.

Cheers.
Jarrod Krige replied to Fusion IT on 11-Aug-10 05:36 AM
Thanks for your previous help.

I am now trying to do a similar thing with DetailsView to Insert as GridView doesn't allow Insert.

Please respond to my new post at
http://www.eggheadcafe.com/community/aspnet/2/10192479/dynamically-creating-fields-for-detailsview-in-c.aspx

Your help would be appreciated.


Thanks~!