,,动态ItemTemplate的实现(译) - item,template
Original:实现动态模板
作者: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.WebControls
namespaceTripleASP。项目模板
{
///摘要
///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
使用系统。Web
namespaceTripleASP。项目模板
{
///摘要
///summarydescriptionforvalidateditem。
////摘要
publicclassValidateEditItem:item plate
{
privatestringcolumn
publicValidateEditItem(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 _ id
datagrid 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控件。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。