图4: GridView调整后的只读界面
我们注意到ProductsRow对象包含产品的CategoryID,CategoryName,SupplierID和SupplierName属性,但是Products数据库只保存了外键,而对应的Name保存在Categories和Suppliers表中。ProductsRow对象中的CategoryID和SupplierID可以读取和写入,而CategoryName和SupplierName属性则标记为只读。
由于CategoryName和SupplierName的只读状态,相应绑定列的ReadOnly属性也被置为true,防止编辑某行时它们的值被修改。尽管也可以通过设置ReadOnly属性为false,使其在编辑状态将这些绑定列转为TextBox,但是这样以来当用户尝试更新产品信息时系统就会抛出异常,因为UpateProduct重载中并不接受CategoryName和SupplierName参数。事实上,我们也不想编写这种重载方法,原因如下:
我们打算在只读模式Supplier和category列分别显示了分类和提供商的名字,而在编辑时,通过下拉列表显示可用选项。这样以来,用户可以快速查看有效的category和supplier并且可以很便捷直观的进行选择。
要实现这一点,需要将SupplierName和CategoryName对应的绑定列转换为模板列,在ItemTemplate模板中显示SupplierName和CategoryName,而EidtItemTemplate模板则使用DropDownList控件列出有效的cagegory和supplier。
添加Categories和Suppliers 的DropDownList控件
我们要先将SupplierName和CategoryName绑定列转换为模板列:点击GridView智能标记中的‘编辑列’链接;选择左下的BoundField;点击“将此字段转换为TemplateField”链接,转换过程将创建一个模板列,包括ItemTemplate和EditItemTemplate,最终的元素标记大致如下:
<asp:TemplateField HeaderText="Category" SortExpression="CategoryName"> <EditItemTemplate> <asp:Label ID="Label1" runat="server" Text=''<%# Eval("CategoryName") %>''></asp:Label> </EditItemTemplate> <ItemTemplate> <asp:Label ID="Label1" runat="server" Text=''<%# Bind("CategoryName") %>''></asp:Label> </ItemTemplate></asp:TemplateField>
由于绑定列标记为只读,ItemTemplate和EditItemTemplate都将用Label控件的Text属性绑定显示相关数据(如上面的CategoryName)。因此需要修改EditItemTemplate模板,用DropDownList控件来替换原来的Label控件。
像上节教程讲的,即可在设计器中编辑模板也可直接修改模板的元素标记。要在设计器中修改,可以通过GridView的智能标记点击“编辑模板”链接并选择Category字段的EditItemTemplate模板。删除Label控件用DropDownList控件代替,并设置DropDownList的ID属性为Categories。
图5:删除EditItemTemplate模板中的TextBox并增加一个DropDownList
下一步我们需要为DropDownList绑定category。从智能标记中点击“选择数据源”链接并选择创建一个新的ObjectDataSource,命名为CategoriesDataSource。
图6:创建一个新的ObjectDataSource控件CategoriesDataSource
为