手机
当前位置:查字典教程网 >编程开发 >asp.net教程 >动态ItemTemplate的实现(译) - item,template
动态ItemTemplate的实现(译) - item,template
摘要:原文:ImplementingDynamicItemTemplatesBy:ScottWatermasyskPublished:4/10/2...

原文:ImplementingDynamicItemTemplates

By:ScottWatermasysk

Published:4/10/2002

翻译:Drason

模版控件能让用户几乎不用花费任何时间就创建出复杂的用户界面.Asp.net有很多控件都使用了模版技术(DataGrid就是一个例子).而这些控件都工作得很好,通常,模版可以被保存为ascx文件以增加复用性.很有可能,事前你是不知道你的控件是怎么布局的,而且你需要动态的添加一些模版以应付不同的事件.

使用模版的另一个优势,就是它们能动态的添加到你的控件里面去.这样的话,你可以事先设计好模版,然后通过简单的几行代码就添加到你的控件中.

下面这篇文章就要告诉你如何如何一步步的添加一个动态的ItemTemplate和EditItemTemplate到DataGrid中.另外,还会告诉你怎么获取和更新用户对EditItemTemplate所做的改变.例子将会是很简单的.然后,我很快就会在TripleASP上面正式发布一个改进后的TableEditor版本.这个版本将更好的说明如何使用动态模版.

ITempalte的实现

为了能动态的添加ItemTemplate和EditItemTemplate,我们需要创建2个类来实现ITemplate的接口(Interface).第一个类是GenericItem.这个类的主要工作就是:取数据源的列名,创建一个文本控件(literalcontral),为这个文本控件赋值,最后把这个文本控件加到父控件(在这里父控件就是DataGrid了).

到目前为止还是很顺利.在继续下面的讨论之前,我们来看看代码和完成的步骤.

usingSystem;

usingSystem.Web;

usingSystem.Data;usingSystem.Web.UI;

usingSystem.Web.UI.WebControls;

namespaceTripleASP.ItemTemplates

{

///<summary>

///SummarydescriptionforGenericItem.

///</summary>

publicclassGenericItem:ITemplate

{

privatestringcolumn;

//privateboolvalidate;

publicGenericItem(stringcolumn)

{

this.column=column;

}

publicvoidInstantiateIn(Controlcontainer)

{

Literall=newLiteral();

l.DataBinding+=newEventHandler(this.BindData);

container.Controls.Add(l);

}

publicvoidBindData(objectsender,EventArgse)

{

Literall=(Literal)sender;

DataGridItemcontainer=(DataGridItem)l.NamingContainer;

l.Text=((DataRowView)container.DataItem)[column].ToString();

}

}

}

正如你看到的,GenericItem类实现了ITemplate的接口(interface).因为我们是实现接口,所以必须包括InstantiateIn这个方法.这个方法是用来定义所有子控件和模版所属的控件对象的.在这个方法里面,我们创建了一个新的Literal控件来保存DataGrid的单元值.接着,我们添加了DataBinding事件处理函数.这个事件处理函数实际上就是在DataGrid绑定数据的时候,把单元值放到Literal控件的Text属性中.最后,把这个Literal控件加入到控件的容器集合中.很简单吧?

动态EditItemTemplate

动态EditItemTemplate类ValidateEditItem跟GenericItem很类似,但是有3个地方不同.

第一个不同的地方是,我们添加的是Textbox控件而不是Literal控件.这样的话,在编辑模式下,用户可以做任何修改.

第二个不同的地方,你会发现我们会显式地命名控件.这会使我们能够获取更新事件中的任何数据变化.

最后一个不同,你会看到一个跟Textbox相联系的RequiredFieldValidator控件.这是可选的.但是,这的确让你知道有些事是可以这样做的.

下面就是ValidateEditItem的代码:

usingSystem;

usingSystem.Data;

usingSystem.Web.UI;

usingSystem.Web.UI.WebControls;

usingSystem.Web;

namespaceTripleASP.ItemTemplates

{

///<summary>

///SummarydescriptionforValidateEditItem.

///</summary>

publicclassValidateEditItem:ITemplate

{

privatestringcolumn;

publicValidateEditItem(stringcolumn)

{

this.column=column;

}

publicvoidInstantiateIn(Controlcontainer)

{

TextBoxtb=newTextBox();

tb.DataBinding+=newEventHandler(this.BindData);

container.Controls.Add(tb);

tb.ID=column;

RequiredFieldValidatorrfv=newRequiredFieldValidator();

rfv.Text="PleaseAnswer";

rfv.ControlToValidate=tb.ID;

rfv.Display=ValidatorDisplay.Dynamic;

rfv.ID="validate"+tb.ID;

container.Controls.Add(rfv);

}

publicvoidBindData(objectsender,EventArgse)

{

TextBoxtb=(TextBox)sender;

DataGridItemcontainer=(DataGridItem)tb.NamingContainer;

tb.Text=((DataRowView)container.DataItem)[column].ToString();

}

}

}

动态模版的实现

现在我们已经有两个实现了ITempalte接口的类了.一切准备好了!我们现在要做的就是把它们加入到我们的datagrid里面.

我们把BindData和DynamicColumns两个方法放在一起.BindData主要是创建SQL查询语句,往datagrid添加列(动态列),然后把数据表绑定到datagrid.

voidBindData()

{

stringsql="Select*frompublishersWhereStateIsnotnull";

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有两个参数:column(字符类型)和isEditable(布尔类型).column变量当然就是我们要加入TemplateColumn的列名.isEditable变量是用作测试的,如果我们希望这个列是允许编辑的话.

protectedTemplateColumnDynamicColumns(stringcolumn,boolisEditable)

{

TemplateColumngenericcolumn=newTemplateColumn();

genericcolumn.HeaderText=column;

genericcolumn.ItemTemplate=newGenericItem(column);

if(isEditable)

{

genericcolumn.EditItemTemplate=newValidateEditItem(column);

}

returngenericcolumn;

}

正如你所看到的,首先我们实例化一个TemplateColumn(genericcolumn),根据我们要添加的列的名字设置HeaderText属性(当然,你可以设置为任何东西都可以).接着,我们通过添加新的GenericItem的参考(reference),把ItemTemplate添加到genericcolumn,并把名称传入.最后,我们必须检查isEditable,以便看看我们需不需要允许编辑这个列.如果为真,我们要往ValidateEditItem添加新的参考,而且把列名也传过去.

DataGrid事件

我们的编辑和取消事件是很标准的.你有可能已经看过它们100遍了.在我们的编辑事件里面,我们简单地取出被选中的行的编号,然后重新绑定数据.

protectedvoidEdit_Click(Objectsender,DataGridCommandEventArgse)

{

DataGrid1.EditItemIndex=e.Item.ItemIndex;

BindData();

}

我们的取消事件是把当前所选行号设为-1.这样就等于告诉datagrid,不在是编辑模式了.然后,我们重新绑定数据.

protectedvoidCancel_Click(Objectsender,DataGridCommandEventArgse)

{

DataGrid1.EditItemIndex=-1;

BindData();

}

更新事件会跟你以前看到的有一点点不同.然而,它却会让你想起你在ASP的日子.

protectedvoidUpdate_Click(Objectsender,DataGridCommandEventArgse)

{

//GetstheUniqueIDthatisattachedtothefrontofeachtextbox

//dyamicallyaddedtoourdatagrid'sEditItemTempate

stringuid=e.Item.UniqueID+":";

stringpub_id=(string)DataGrid1.DataKeys[e.Item.ItemIndex];

stringpub_name=(Request.Form[uid+"pub_name"].ToString());

stringcity=(Request.Form[uid+"city"].ToString());

stringstate=(Request.Form[uid+"state"].ToString());

stringcountry=(Request.Form[uid+"country"].ToString());

//SimplemethodtoupdateDB

UpdateRecord(pub_id,pub_name,city,state,country);

DataGrid1.EditItemIndex=-1;

BindData();

}

这样的话,EditItemTemplate就硬编码到页面中去了.你可能已经看过一些取表单提交数据的例子,其中的方法,或者是通过控件位置取值,或者是控件名称取值.但是,如果你是在运行时创建控件,那么,在PostBack的时候,ASP.NET是无法取得这些值的.为此,我们只能通过Request.Form的方法来得到这些值.

在你开始在ValidateEditItem类里面仔细寻找被小心命名的textbox的时候,你必须记住,ASP.NET已经为控件的名字冲突做了预防措施.一般来说,这包括增加每个datagrid父控件的名称,datagrid本身的名称,和一个代表每个textbox的序号的字符串放在textbox的ID前面.我们可以大量的使用这样的方法.但是这并不保证我们的代码绝对的模块化和可复用.相反,我们检查DataGridCommandEventArgs.Item.UniqueID并在尾部加上":".有了这个UniqueID,我们就可以安全地取得textbox里面的编辑数据,并更新到数据库.

结论

动态添加模版到你的模版控件会在开始的时候增加一点点的工作量.但是,一旦你建立了一系列的优秀的模版类,你会发现,实现ITemplate会非常的快速和容易.它运行你建立强大的控件来满足你数据操作的需要.如果你需要更好的例子,请看我即将发布在TripleASP的TableEditor控件.

【动态ItemTemplate的实现(译) - item,template】相关文章:

AlternatingItemTemplate类似于 ItemTemplate 元素

Convert.ToInt32与Int32.Parse区别及Int32.TryParse

.Net 文本框实现内容提示的实例代码

asp.net动态加载自定义控件的方法

ASP.NET 2.0下的条件编译

xenocode代码混淆加密的操作步骤

asp.net实现文件无刷新上传方法汇总

常用的在数据库中建立无限级树形菜单的asp.net代码

asp.net导出EXCEL的功能代码

mstest实现类似单元测试nunit中assert.throws功能

精品推荐
分类导航