Code for dynamically adding a template column to the DataGrid

Source: Internet
Author: User

Another advantage of using templates is that they can be dynamically added to your controls. in this way, you can design a template in advance and add it to your control through a few simple lines of code.

The following article will show you how to add a dynamic ItemTemplate and EditItemTemplate to the DataGrid step by step. in addition, it will tell you how to obtain and update the user's changes to EditItemTemplate. the example will be very simple. then, I will soon officially release an improved version of TableEditor on TripleASP. this version will better illustrate how to use dynamic templates.


Implementation of ITempalte
To dynamically add ItemTemplate and EditItemTemplate, we need to create two classes to implement the ITemplate Interface ). the first class is GenericItem. the main work of this class is to take the name of the data source column, create a text control (literal contral), assign a value to this text control, add the text control to the parent control (the parent control is the DataGrid ).

So far it has been quite smooth. Before continuing the discussion below, let's take a look at the code and complete the steps.
Using System;
Using System. Web;
Using System. Data; using System. Web. UI;
Using System. Web. UI. WebControls;

Namespace TripleASP. ItemTemplates
{
/// <Summary>
/// Summary description for GenericItem.
/// </Summary>
Public class GenericItem: ITemplate
{
Private string column;
// Private bool validate;
Public GenericItem (string column)
{
This. column = column;
}
Public void InstantiateIn (Control container)
{
Literal l = new Literal ();
L. DataBinding + = new EventHandler (this. BindData );
Container. Controls. Add (l );
}

Public void BindData (object sender, EventArgs e)
{
Literal l = (Literal) sender;
DataGridItem container = (DataGridItem) l. NamingContainer;
L. Text = (DataRowView) container. DataItem) [column]. ToString ();

}
}
}

As you can see, the GenericItem class implements the ITemplate interface ). because we implement the interface, we must include the InstantiateIn method. this method is used to define the control objects of all child controls and templates. in this method, we create a new Literal control to save the cell value of the DataGrid. next, we added the DataBinding event processing function. this event processing function actually places the unit value in the Text attribute of the Literal control when binding data to the DataGrid. finally, add the Literal control to the container collection of the control. is it easy?

Dynamic EditItemTemplate
Dynamic EditItemTemplate ValidateEditItem is similar to GenericItem, but there are three differences.
The first difference is that the Textbox Control is added instead of the Literal control. In this way, you can make any modifications in editing mode.
In the second place, you will find that we will explicitly name the control. This will allow us to obtain any data changes in the update event.
The last difference is that you will see a RequiredFieldValidator control associated with Textbox. This is optional. However, it does let you know that some things can be done in this way.
The following is the ValidateEditItem code:
Using System;
Using System. Data;
Using System. Web. UI;
Using System. Web. UI. WebControls;
Using System. Web;

Namespace TripleASP. ItemTemplates
{
/// <Summary>
/// Summary description for ValidateEditItem.
/// </Summary>
Public class ValidateEditItem: ITemplate
{
Private string column;
Public ValidateEditItem (string column)
{
This. column = column;
}

Public void InstantiateIn (Control container)
{
TextBox tb = new TextBox ();
Tb. DataBinding + = new EventHandler (this. BindData );
Container. Controls. Add (tb );
Tb. ID = column;

RequiredFieldValidator rfv = new RequiredFieldValidator ();
Rfv. Text = "Please Answer ";
Rfv. ControlToValidate = tb. ID;
Rfv. Display = ValidatorDisplay. Dynamic;
Rfv. ID = "validate" + tb. ID;
Container. Controls. Add (rfv );

}

Public void BindData (object sender, EventArgs e)
{
TextBox tb = (TextBox) sender;
DataGridItem container = (DataGridItem) tb. NamingContainer;
Tb. Text = (DataRowView) container. DataItem) [column]. ToString ();
}
}
}

Dynamic template implementation
Now we have two classes that implement the ITempalte interface. Everything is ready! What we need to do now is to add them to our datagrid.

We put BindData and DynamicColumns together. BindData mainly creates SQL query statements, adds columns (Dynamic columns) to the datagrid, and then binds the data table to the datagrid.

Void BindData ()
{
String SQL = "Select * from publishers Where State Is not null ";
DataGrid1.Columns. Add (DynamicColumns ("pub_id", false ));
DataGrid1.Columns. Add (DynamicColumns ("pub_name", true ));
DataGrid1.Columns. Add (DynamicColumns ("city", true ));
DataGrid1.Columns. Add (DynamicColumns ("state", true ));
DataGrid1.Columns. Add (DynamicColumns ("country", true ));
DataGrid1.DataKeyField = "pub_id ";
DataGrid1.DataSource = GetDataTable (SQL );
DataGrid1.DataBind ();
}

DynamicColumns has two parameters: column (character type) and isEditable (boolean type ). the column variable is the name of the column to be added to the TemplateColumn. the isEditable variable is used for testing, if we want this column to be editable.
Protected TemplateColumn DynamicColumns (string column, bool isEditable)
{
TemplateColumn genericcolumn = new TemplateColumn ();
Genericcolumn. HeaderText = column;
Genericcolumn. ItemTemplate = new GenericItem (column );
If (isEditable)
{
Genericcolumn. EditItemTemplate = new ValidateEditItem (column );
}
Return genericcolumn;
}

As you can see, first we instantiate a TemplateColumn (genericcolumn) and set the HeaderText Attribute Based on the name of the column we want to add (of course, you can set it to anything ). next, we add the ItemTemplate to genericcolumn by adding the reference of the new GenericItem, and pass the name in. finally, we must check the isEditable to see if we need to allow editing of this column. if it is true, we will add a new reference to ValidateEditItem and pass the column name to it.


DataGrid event
Our editing and cancellation events are very standard. you may have seen them 100 times. in our editing event, we simply retrieve the number of the selected row and rebind the data.

Protected void Edit_Click (Object sender, DataGridCommandEventArgs e)
{
DataGrid1.EditItemIndex = e. Item. ItemIndex;
BindData ();
}
Our cancellation event is to set the currently selected row number to-1. This will tell the datagrid that it is not in edit mode. Then, we rebind the data.
Protected void Cancel_Click (Object sender, DataGridCommandEventArgs e)
{
DataGrid1.EditItemIndex =-1;
BindData ();
}
The update event is a little different from what you saw before. However, it reminds you of your ASP day.
Protected void Update_Click (Object sender, DataGridCommandEventArgs e)
{
// Gets the UniqueID that is attached to the front of each textbox
// Dyamically added to our datagrid's EditItemTempate
String uid = e. Item. UniqueID + ":";

String pub_id = (string) DataGrid1.DataKeys [e. Item. ItemIndex];
String pub_name = (Request. Form [uid + "pub_name"]. ToString ());
String city = (Request. Form [uid + "city"]. ToString ());
String state = (Request. Form [uid + "state"]. ToString ());
String country = (Request. Form [uid + "country"]. ToString ());

// Simple method to update DB
UpdateRecord (pub_id, pub_name, city, state, country );
DataGrid1.EditItemIndex =-1;
BindData ();
}

In this case, EditItemTemplate is hardcoded to the page. you may have read some examples of using the form to submit data, the method in which the data is obtained, the value of the control location, or the value of the Control name. however, if you create a control at runtime, ASP. NET cannot obtain these values. therefore, we can only use Request. form method to obtain these values.

When you start to look for textbox named carefully in the ValidateEditItem class, you must remember that ASP. NET has taken preventive actions for control name conflicts. in general, this includes adding the name of each datagrid parent control, the name of the datagrid itself, and a string representing the serial number of each textbox before the textbox ID. we can use this method a lot. however, this does not ensure that our code is absolutely modular and reusable. instead, we check the DataGridCommandEventArgs. item. uniqueID and add ":". with this UniqueID, We can securely retrieve the edited data in the textbox and update it to the database.


Conclusion
Adding a template to your template control dynamically adds a little workload at the beginning. however, once you create a series of excellent template classes, you will find that implementing ITemplate is very fast and easy. it runs a powerful control to meet your data operation needs. if you need a better example, please refer to the TableEditor control I am about to publish in TripleASP.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.