动态ItemTemplate的实现(译) - item,template
• 经验
动态ItemTemplate的实现(译) - item,templateOriginal:实现动态模板作者:ScottWatermasysk发布日期:2002年10月4日翻译:道森模板允许用户创建复杂的用户界面,几乎不需要花费任何时间。Asp.net的许多控件都使用模板技术(数据网格就是一个例子)。这些控制都很好。通常,模板可以保存为ascx文件,以增加可重用性。很有可能你事先不知道你的控件是怎么布局的,需要动态添加一些模板来应对不同的事件。使用模板的另一个优点是可以动态地将它们添加到控件中。这样,您可以预先设计模板,然后用几行简单的代码将它们添加到控件中。下面的文章将告诉您如何一步一步地向DataGrid添加动态ItemTemplate和EditItemTemplate。此外,它将告诉您如何获取和更新用户对EditItemTemplate所做的更改。这些例子非常简单。然后,我很快会在TripleASP上正式发布TableEditor的改进版。这个版本将更好地解释如何使用动态模板。ITemplate的实现为了动态添加ItemTemplate和EditItemTemplate,我们需要创建两个类来实现item plate的接口。第一个类是GenericItem。这个类的主要工作是获取数据源的列名,创建一个literalcontral,为这个文本控件赋值,最后将这个文本控件添加到父控件中(这里父控件是DataGrid)。到目前为止,一切顺利。在继续下面的讨论之前,让我们看一下代码和完成的步骤。使用系统;使用系统。Web使用系统。数据;使用系统。Web . UI使用系统。Web . UI.WebControlsnamespaceTripleASP。项目模板{///摘要///SummarydescriptionforGenericItem。////摘要publicsclassgenericitem:item plate{privatestringcolumn//privateboolvalidate;publicGenericItem(stringcolumn){this.column=列;}publicvoidinstantein(control container){literall=new literal();长度data binding=new eventhandler(this。bind data);集装箱。controls . Add(l);}publicvoidBindData(object sender,EventArgse){Literall=(文字)发送者;DataGridItemcontainer=(DataGridItem)l . naming container;长度Text=((DataRowView)容器。DataItem)[列]。ToString();}}}可以看到,GenericItem类实现了ITemplate的接口。因为我们正在实现接口,所以我们必须在方法中包含InstantiateIn。此方法用于定义所有子控件和模板所属的控件对象。在这个方法中,我们创建了一个新的文本控件来保存DataGrid的单元格值。然后,我们添加了数据绑定事件处理程序。当DataGrid绑定数据时,该事件处理程序实际上将单元格值放入Literal控件的Text属性中。最后,此文本控件被添加到控件的容器集合中。很简单吧?动态编辑项模板动态EditItemTemplate类ValidateEditItem类似于GenericItem,但有三个不同之处。第一个区别是我们添加了一个Textbox控件而不是一个Literal控件。这样,用户可以在编辑模式下进行任何更改。第二个区别是,你会发现我们显式地命名了控件。这将使我们能够在更新事件中获得任何数据更改。最后一个区别是,您将看到一个与Textbox关联的RequiredFieldValidator控件。这是可选的。但是,它确实让你知道有些事情是可以做到的。以下是ValidateEditItem的代码:使用系统;使用系统。数据;使用系统。Web . UI使用系统。Web . UI.WebControls使用系统。WebnamespaceTripleASP。项目模板{///摘要///summarydescriptionforvalidateditem。////摘要publicclassValidateEditItem:item plate{privatestringcolumnpublicValidateEditItem(string column){this.column=列;}publicvoidinstantein(control container){textbox TB=new textbox();肺结核。data binding=new eventhandler(this。bind data);集装箱。controls . Add(TB);肺结核。ID=列;RequiredFieldValidatorrfv=newRequiredFieldValidator();rfv .请回答rfv .ControlToValidate=tb .ID;rfv .显示=验证显示.动态;rfv .ID=“验证”tb .ID;集装箱10 .控制。添加(rfv);}publicvoidBindData(对象发送方,EventArgse){TextBoxtb=(文本框)发送方;DataGridItemcontainer=(DataGridItem)TB .命名容器;肺结核Text=((DataRowView)容器DataItem)[列]。ToString();}}}动态模版的实现现在我们已经有两个实现了ITempalte接口的类了。一切准备好了!我们现在要做的就是把它们加入到我们的数据网格里面。我们把绑定数据和动态列两个方法放在一起。绑定数据主要是创建结构化查询语言查询语句,往数据网格添加列(动态列),然后把数据表绑定到数据网格。voidBindData(){string SQL= Select * from publishers where stateisnotnull ;datagrid 1列。Add(动态列( pub _ id ,false));datagrid 1列。Add(动态列( pub _ name ,true));datagrid 1列。Add(动态列( city ,true));datagrid 1列。Add(动态列( state ,true));datagrid 1列。Add(动态列( country ,true));DataGrid1DataKeyField= pub _ iddatagrid 1 data source=get datatable(SQL);datagrid 1 databind();}动态列有两个参数:列(字符类型)和isEditable(布尔类型).圆柱变量当然就是我们要加入模板列的列名106 . isEditable变量是用作测试的,如果我们希望这个列是允许编辑的话。protectedTemplateColumnDynamicColumns(字符串列,boolisEditable){模板列泛型列=新模板列();泛型列HeaderText=列泛型列item template=newGenericItem(column);if(isEditable){泛型列edit item template=newvalidateditem(column);}returngenericcolumn}正如你所看到的,首先我们实例化一个TemplateColumn(genericcolumn),根据我们要添加的列的名字设置标题文本属性(当然,你可以设置为任何东西都可以).接着,我们通过添加新的通用项目的参考(参考),把项目模板添加到泛型列,并把名称传入。最后,我们必须检查isEditable,以便看看我们需不需要允许编辑这个列。如果为真,我们要往ValidateEditItem添加新的参考,而且把列名也传过去。数据网格事件我们的编辑和取消事件是很标准的。你有可能已经看过它们100遍了。在我们的编辑事件里面,我们简单地取出被选中的行的编号,然后重新绑定数据。protectedvoidEdit _ Click(对象发送方,DataGridCommandEventArgse){DataGrid1EditItemIndex=e . item。项目索引;bind data();}我们的取消事件是把当前所选行号设为-1.这样就等于告诉数据网格,不在是编辑模式了。然后,我们重新绑定数据。protectedvoidCancel _ Click(对象发送方,DataGridCommandEventArgse){datagrid 1 edititemindex=-1;bind data();}更新事件会跟你以前看到的有一点点不同。然而,它却会让你想起你在动态服务器页面的日子。protectedvoidUpdate _ Click(对象发送方,DataGridCommandEventArgse){//GetstheUniqueIDthatisattachedtothefrontofeachtextbox//dyamicallyaddedtoourdatagrid sedititemtempate字符串guid=e . item。uniqueid“:”;stringpub_id=(string)DataGrid1 .数据键。项目索引];stringpub_name=(请求。表单[uid pub_name].ToString());stringcity=(请求。表单[uid city].ToString());stringstate=(请求。表单[uid state].ToString());stringcountry=(请求。表单[uid 国家].ToString());//SimplemethodtoupdateDB更新记录(发布标识,发布名称,城市,州,国家);datagrid 1 edititemindex=-1;bind data();}这样的话,编辑项目模板就硬编码到页面中去了。你可能已经看过一些取表单提交数据的例子,其中的方法,或者是通过控件位置取值,或者是控件名称取值。但是,如果你是在运行时创建控件,那么,在回发的时候,ASP .网是无法取得这些值的。为此,我们只能通过请求。形式的方法来得到这些值。当你开始仔细搜索ValidateEditItem类中精心命名的textbox时,你必须记住ASP.NET已经采取了预防措施来防止控件的名称冲突。一般来说,这包括添加每个datagrid父控件的名称,datagrid本身的名称,以及在textbox的id前面放置一个表示每个textbox的序列号的字符串。我们可以大量使用这种方法。然而,它不能保证我们的代码是绝对模块化和可重用的。相反,我们检查datagridcommandventargs . item . uniqueid并在末尾添加:。有了这个uniqueid,我们可以安全地获取文本框中编辑过的数据,并将其更新到数据库中。结论在模板控件中添加动态模板会在开始时增加一点工作量。但是,一旦你建立了一系列优秀的模板类,你会发现实现ITemplate是非常快速和容易的。它让您构建强大的控件来满足您的数据操作需求。如果需要更好的例子,请看我即将在TripleASP中发布的TableEditor控件。