导言
在前面我们学习了如何创建item级的DataList。和可编辑的GridView一样,每个DataList里的item都包含一个Edit button,当点击时,item会变的可编辑。item级的编辑在偶尔需要更新时没什么问题,但是在有些情况下用户需要编辑大量的记录。如果一个用户需要编辑许多记录,他会被迫去不停的去点击Edit,作出修改,然后点击Update,这些大量的点击会妨碍他的工作效率。在这样的情况下,一个好的选择是提供一个完全可编辑的DataList,它的所有的item都处于编辑模式下,它的所有的值都可以通过点击一个“Update All”button来更新。见图1。
图 1: 一个完全可编辑的DataList 的所有item都可以被修改
本章我们来学习如何创建一个完全可编辑的DataList,它提供用户更新supplier的address的功能。
第一步: 在DataList的 ItemTemplate创建一个可编辑的用户界面
在前面创建一个标准的item级编辑的DataList时,我们使用了两个template:
ItemTemplate — 包含只读的用户界面(使用 Label 显示每个product的 name 和price).
EditItemTemplate — 包含编辑的用户界面(两个TextBox ).
DataList的EditItemIndex属性表明了哪个DataListItem使用EditItemTemplate来展示(如果有的话)。即ItemIndex的值等于DataList的EditItemIndex的DataListItem使用EditItemTemplate来展示。在一次只编辑一个item的情况下,这个模式工作的很好,但是在创建完全可编辑的DataList的时候就不适用了。
对完全可编辑的DataList来说,我们需要所有的DataListItem都以可编辑的界面来展示。最简单的方法是在ItemTemplate里定义可编辑的界面。对修改supplier的address信息而言,可编辑界面里supplier表现为文本,address,city和country的值都用TextBox来表示。
首先打开BatchUpdate.aspx页,添加一个DataList,将ID设为Suppliers。通过智能标签添加一个名为SuppliersDataSource的ObjectDataSource控件。
图2: 创建一个名为SuppliersDataSource的ObjectDataSource
使用SuppliersBLL类的GetSuppliers()方法配置ObjectDataSource(见图3)。象前面一章那样,我们将直接使用 BLL而不是通过ObjectDataSource来更新supplier信息。在UPDATE标签里选择None(见图4)。
图 3: 使用GetSuppliers() 方法配置ObjectDataSource
图 4: 设置UPDATE 标签为None
完成向导后,Visual Studio会自动生成DataList的ItemTemplate来在Label里显示每个数据字段。我们需要修改这个template让它提供编辑界面。ItemTemplate可以在设计器里通过DataList的智能标签上的Edit Templates或直接写声明语法来自定义。
创建一个编辑界面,将supplier的name表现为文本,address,city和country表现为TextBox。完成这些后,你的声明代码应该和下面差不多:
<asp:DataList ID="Suppliers" runat="server" DataKeyField="SupplierID" DataSourceID="SuppliersDataSource"> <ItemTemplate> <h4><asp:Label ID="CompanyNameLabel" runat="server" Text='<%# Eval("CompanyName") %>' /></h4> <table border="0"> <tr> <td class="SupplierPropertyLabel">Address:</td> <td class="SupplierPropertyValue"> <asp:TextBox ID="Address" runat="server" Text='<%# Eval("Address") %>' /> </td> </tr> <tr> <td class="SupplierPropertyLabel">City:</td> <td class="SupplierPropertyValue"> <asp:TextBox ID="City" runat="server" Text='<%# Eval("City") %>' /> </td> </tr> <tr> <td class="SupplierPropertyLabel">Country:</td> <td class="SupplierPropertyValue"> <asp:TextBox ID="Country" runat="server" Text='<%# Eval("Country") %>' /> </td> </tr> </table> <br /> </ItemTemplate> </asp:DataList> <asp:ObjectDataSource ID="SuppliersDataSource" runat="server" OldValuesParameterFormatString="original_{0}" SelectMethod="GetSuppliers" TypeName="SuppliersBLL"> </asp:ObjectDataSource></div>
注意:和前面一章一样,需要为DataList开启view state。
在ItemTemplate里我使用了两个新的CSS类,SupplierPropertyLabel和SupplierPropertyValue。它们的风格设置和ProductsPropertyLabel和ProductPropertyValue CSS类一样,并已经加入到Styles.css中。
.ProductPropertyLabel, .SupplierPropertyLabel { font-weight: bold; text-align: right; } .ProductPropertyValue, .SupplierPropertyValue { padding-right: 35px; }</div>
完成这些后浏览页面。如图5所示,每个DataList的item用文本显示supplier name,用TextBox显示address,city和country。
图 5: DataList里的每个Supplier都可编辑
第二步: 增加“Update All” Button
图5里显示的信息暂时还没提供Update按钮。完全可编辑的DataList应该只包含一个"Update All"按钮,而不是象前面那样,每个item包含一个button。当点击"Update All"时,DataList里的所有记录将被更新。本章我们将添加两个"Update All"button- 一个在页的上面,一个在下面(两个都提供相同的功能)。
先在DataList上面添加一个ID为UpdateAll1的Button。然后在DataList下面添加ID为UpdataAll2的Button。两个Button的Text都设为"Update All"。最后为两个Button的Click事件都创建一个event handler。我们创建一个方法,“UpdateAllSupplierAddress”,然后在事件处理中调用它。(而不是在两个事件处理里复制相同的代码)
protected void UpdateAll1_Click(object sender, EventArgs e) { UpdateAllSupplierAddresses(); } protected void UpdateAll2_Click(object sender, EventArgs e) { UpdateAllSupplierAddresses(); } private void UpdateAllSupplierAddresses() { // TODO: Write code to update _all_ of the supplier addresses in the DataList }</div>
图6是添加完"Update All"button后的页面。
图 6: 页面添加了两个“Update All” Button
第三步: 更新所有的Suppliers的 Address 信息
完成了将所有的item显示为可编辑的界面和添加了“Update All”button后,剩下的事就是写代码执行批量更新。我们需要便利DataList的item,调用SuppliersBLL类的UpdateSupplierAddress方法。
可以通过DataList的Items property 来访问DataListItem集合。通过DataListItem的引用,我们可以从DataKeys集合里获取相关的SuppliserID,并引用ItemTemplate里的TextBox,见下面的代码:
private void UpdateAllSupplierAddresses() { // Create an instance of the SuppliersBLL class SuppliersBLL suppliersAPI = new SuppliersBLL(); // Iterate through the DataList's items foreach (DataListItem item in Suppliers.Items) { // Get the supplierID from the DataKeys collection int supplierID = Convert.ToInt32(Suppliers.DataKeys[item.ItemIndex]); // Read in the user-entered values TextBox address = (TextBox)item.FindControl("Address"); TextBox city = (TextBox)item.FindControl("City"); TextBox country = (TextBox)item.FindControl("Country");