公司最近的一个项目需要涉及到动态订单,即每位用户订单数据表的属性列是可以自定义的,数据表字段是动态的,所以使用GridView等控件对未知数据表进行操作时,需要使用动态模板。实现如下:

为GridView控件创建自定义模板

当使用模板控件时,可能直到运行时还不了解所需要的模板,或者模板中应该包括的文本或者控件。在这种情况下,可以在代码中动态创建模板。可以在代码中为所有使用模板的控件创建模板:DataList、Repeater、GridView、FormView、DetailsView等。对于GridView控件而言,使用模板可定义列,而不是其他控件那样的行布局模板。下面实例将介绍使用GridView控件自定义模板的应用程序。

GridView模板是实现ITemplate接口的类。该类定义了将在GridView列中显示的控件,以及数据如何绑定这些控件,同时还能够通过一些特定代码来处理页眉和页脚。就本例而言,将从零开始讲解一个简化的GridView示例,它使用模板格式化GridView的内容。虽然这个示例非常简单,但很多复杂的情况都可以通过扩展该示例实现。下面开始介绍自定义模板类的实现。

1.创建自定义模板类

自定义模板类(名称为CustomGridViewTemplate)包括的代码放置在GridView控件中,这些代码内的控件完成实际工作格式化控件,绑定数据的工作。由于CustomGridViewTemplate类实现ITemplate接口,所以该类提供了InstantiateIn()方法的实现。在该方法中定义了生成包括子控件的GridView控件的行为。示例一列举了该类的实现代码。

示例一:使用自定义模板格式化GridView


Code1 publicclassCustomGridViewTemplate : ITemplate2 {3 privateDataControlRowType _templateType;4 privatestring_columnName;5 privatestring_dataType;6 publicCustomGridViewTemplate(DataControlRowType templateType,7 stringcolumnName,stringdataType)8 {9 _templateType=templateType;10 _columnName=columnName;11 _dataType=dataType;12 }13 ///14 ///此方法为 GridView执行DataBind方法后触发执行15 ///按行顺序向下执行(行->行中各列)16 ///17 ///18 publicvoidInstantiateIn(System.Web.UI.Control container)19 {20 switch(_templateType)21 {22 caseDataControlRowType.Header:23 //创建当前列的标题24 Literal literal=newLiteral();25 literal.Text=""+_columnName+"";26 container.Controls.Add(literal);27 break;28 caseDataControlRowType.DataRow:29 //创建当前列的一行30 Label label=newLabel();31 switch(_dataType)32 {33 case"DateTime":34 label.ForeColor=System.Drawing.Color.Blue;35 break;36 case"Double":37 label.ForeColor=System.Drawing.Color.Violet;38 break;39 case"Int32":40 label.ForeColor=System.Drawing.Color.Green; ;41 break;42 case"String":43 label.ForeColor=System.Drawing.Color.Brown;44 break;45 default:46 label.ForeColor=System.Drawing.Color.Green;47 break;48 }49 //注册用于数据绑定的事件处理程序50 label.DataBinding+=newEventHandler(this.label_DataBinding);51 container.Controls.Add(label);52 break;53 default:54 break;55 }56 }57 58 ///59 ///当InstantiateIn执行完一行后,统一触发该绑定事件处理方法60 ///61 ///62 ///63 privatevoidlabel_DataBinding(Object sender, EventArgs e)64 {65 //获取触发时间的控件66 Label label=(Label)sender;67 //获取容器行68 GridViewRow row=(GridViewRow)label.NamingContainer;69 //获取行数据值,并将其格式化70 stringrawValue=DataBinder.Eval(row.DataItem, _columnName).ToString();71 switch(_dataType)72 {73 case"DateTime":74 label.Text=String.Format("{0:d}", DateTime.Parse(rawValue));75 break;76 case"Double":77 label.Text=String.Format("{0:###,###,##0.00}",78 Double.Parse(rawValue));79 break;80 default:81 label.Text=rawValue;82 break;83 }84 }85

本例仅使用了文本标签来显示数据,但是并不限于单个控件。该方法还通过注册事件处理程序来设置数据绑定:

// 为执行数据绑定注册事件处理程序
label.DataBinding += new EventHandler(this.label_DataBinding);

正如所期待的那样,当数据绑定到GridView时会调用数据绑定事件处理程序。在数据绑定事件处理程序中,获取了指向控件容器的引用,同时还格式化了数据。

2.使用模板

如果将CustomGridViewTemplate类存储到App_Code文件夹中,那么对于Web站点的所有ASP.NET页面而言,都可以使用该类。示例二列举了如何通过GridView控件使用CustomGridViewTemplate。
.CS文件

CodeusingSystem;usingSystem.Data;usingSystem.Configuration;usingSystem.Web;usingSystem.Web.Security;usingSystem.Web.UI;usingSystem.Web.UI.WebControls;usingSystem.Web.UI.WebControls.WebParts;usingSystem.Web.UI.HtmlControls;usingSystem.Collections;usingSystem.Data.SqlClient;usingSystem.Web.Configuration;publicpartialclass_Default : System.Web.UI.Page
{protectedvoidPage_Load(objectsender, EventArgs e)
{if(!IsPostBack)
{stringconnectionString=WebConfigurationManager.ConnectionStrings["strDBConn"].ConnectionString;
DataTable deptTable=newDataTable();using(SqlConnection connection=newSqlConnection(connectionString))
{stringsql="select * from province";
SqlCommand command=newSqlCommand(sql);
command.CommandType=CommandType.Text;
command.Connection=connection;
SqlDataAdapter adapter=newSqlDataAdapter();
adapter.SelectCommand=command;
adapter.Fill(deptTable);
}//清除当前存在的列//deptView.Columns.Clear();//递归DataTable,将列添加到GridView中for(inti=0; i
{
TemplateField templateField=newTemplateField();//创建数据行templateField.ItemTemplate=newCustomGridViewTemplate
(DataControlRowType.DataRow,
deptTable.Columns[i].ColumnName,
deptTable.Columns[i].DataType.Name);//创建标题templateField.HeaderTemplate=newCustomGridViewTemplate
(DataControlRowType.Header, deptTable.Columns[i].ColumnName,
deptTable.Columns[i].DataType.Name);//将其添加到GridViewdeptView.Columns.Add(templateField);
}//绑定并显示数据deptView.DataSource=deptTable;
deptView.DataBind();
ViewState["DbPrivance"]=deptTable;
}
}protectedvoidBtnDel_Click(objectsender, EventArgs e)
{
DataTable deptTable=ViewState["DbPrivance"]asDataTable;for(inti=deptView.Rows.Count-1; i>=0; i--)
{stringstrID="";
CheckBox cbox=deptView.Rows[i].FindControl("CBoxSelected")asCheckBox;if(cbox!=null)
{boolisChecked=cbox.Checked;//调用删除操作方法}
}for(inti=0; i
{
TemplateField templateField=newTemplateField();//创建数据行templateField.ItemTemplate=newCustomGridViewTemplate
(DataControlRowType.DataRow,
deptTable.Columns[i].ColumnName,
deptTable.Columns[i].DataType.Name);//创建标题templateField.HeaderTemplate=newCustomGridViewTemplate
(DataControlRowType.Header, deptTable.Columns[i].ColumnName,
deptTable.Columns[i].DataType.Name);//将其添加到GridViewdeptView.Columns.Add(templateField);
}this.deptView.DataSource=deptTable;this.deptView.DataBind();
}
}publicclassCustomGridViewTemplate : ITemplate
{privateDataControlRowType _templateType;privatestring_columnName;privatestring_dataType;publicCustomGridViewTemplate(DataControlRowType templateType,stringcolumnName,stringdataType)
{
_templateType=templateType;
_columnName=columnName;
_dataType=dataType;
}//此方法为 GridView执行DataBind方法后触发执行///按行顺序向下执行(行->行中各列)//publicvoidInstantiateIn(System.Web.UI.Control container)
{switch(_templateType)
{caseDataControlRowType.Header://创建当前列的标题Literal literal=newLiteral();
literal.Text=""+_columnName+"";
container.Controls.Add(literal);break;caseDataControlRowType.DataRow://创建当前列的一行Label label=newLabel();switch(_dataType)
{case"DateTime":
label.ForeColor=System.Drawing.Color.Blue;break;case"Double":
label.ForeColor=System.Drawing.Color.Violet;break;case"Int32":
label.ForeColor=System.Drawing.Color.Green; ;break;case"String":
label.ForeColor=System.Drawing.Color.Brown;break;default:
label.ForeColor=System.Drawing.Color.Green;break;
}//注册用于数据绑定的事件处理程序label.DataBinding+=newEventHandler(this.label_DataBinding);
container.Controls.Add(label);break;default:break;
}
}//当InstantiateIn执行完一行后,统一触发该绑定事件处理方法/privatevoidlabel_DataBinding(Object sender, EventArgs e)
{//获取触发时间的控件Label label=(Label)sender;//获取容器行GridViewRow row=(GridViewRow)label.NamingContainer;//获取行数据值,并将其格式化stringrawValue=DataBinder.Eval(row.DataItem, _columnName).ToString();switch(_dataType)
{case"DateTime":
label.Text=String.Format("{0:d}", DateTime.Parse(rawValue));break;case"Double":
label.Text=String.Format("{0:###,###,##0.00}",
Double.Parse(rawValue));break;default:
label.Text=rawValue;break;
}
}
}
.ASPX文件