使用模板编辑的一个最重要的原因是为了提供更好的编辑体验。
实现编辑最简便的方式是加入一个ShowEditButton的属性值为真(或者GridView.AutoGrnerateEditButton属性为真)的CommandField列。不管用哪种方法,都必须以用于显示编辑命令的专用列结束。起初,这个列将挨着每条记录显示名为编辑的链接。当用户单击编辑链接时,该行中的所有列由标记变成了文本框(只读字段除外)。
在模板列中,可以使用EditItem Template定义编辑控件以及它们的布局,不过这个过程有点费劲。
下面这个编辑模板允许你编辑单个字段---Notes字段
<EditItemTemplate> <b> <%# Eval("TitleOfCourse") %> - <%# Eval("EmployeeID") %> <%# Eval("FirstName") %> <%# Eval("LastName") %> </b> <hr /> <small><i> <%# Eval("Address") %><br /> <%# Eval("City") %>, <%# Eval("Country") %>, <%# Eval("PostalCode") %><br /> <%# Eval("HomePhone") %></i> <br /><br /> <asp:TextBox Text='<%# Bind("Notes") %>' runat="server" id="textBox" Font-Names="Verdana" Font-Size="XX-Small" Height="40px" TextMode="MultiLine" Width="413px" /> <br /><br /> </small> </EditItemTemplate>
绑定一个编辑值到字段时,必须在数据绑定表达式中使用bind()方法而不是通常的Eval()方法。只有bind()方法才会创建双向链接,这样更新后的值才能回送到服务器。
还需要记住的一点是,当GridView提交更新时,它只提交被绑定的,可编辑的参数。在上面代码中,GridView将只为Notes字段回传@Notes参数。这一点很重要,因为当编写参数化的更新命令时,只能使用一个参数。
1.使用高级控件编辑
修改前面的示例使得TitleOfCourse字段可通过下拉列表框来编辑。修改后的代码如下:
<b>
<%# Eval("EmployeeID") %> -
<asp:DropDownList runat="server" ID="EditTitle"
SelectedIndex='<%# GetSelectedTitle(Eval("TitleOfCourtesy")) %>'
Font-Names="Verdana" Font-Size="XX-Small"
DataSource='<%# TitlesOfCourtesy %>' />
<%# Eval("FirstName") %>
<%# Eval("LastName") %>
</b>
这个模板允许用户从一个有限的可能选项中选择称呼。要创建这个列表,需要一点小技巧---把DropDownList.DataSource设置为一个纸箱自定义属性的数据绑定表达式。这个自定义的属性返回一个包含可用称呼的数据源。
以下是网页类中,TitleOfCourse属性的定义:
protected string[] TitlesOfCourtesy
{
get
{
return new string[] { "Mr.", "Dr.", "Ms.", "Mrs." };
}
}
这段代码使用静态方法Array.Index()搜索数组。请注意你必须显示显示地把称呼转换成字符串。因为DataBinder.Eval()方法返回对象而不是字符串,而该值需要传送给GetSelectedTitle()方法。
现在列表框在编辑模式下被填充,且正确的项目自动被选定。但如果改变了选择项,选定的值将不会被回送到数据源,在这个实例里,可以使用Binding()方法通过SelectedValue属性来解决这个问题,因为控件中的文字完全和要提交的记录匹配。不过问题并非总是如此简单,你可能要把选定的值转换为一个不同的数据库代码,遇到这样的情况时,唯一的选择是处理RowUpdating事件,找到当前行的列表控件,解析出文本,然后就可以动态加入额外的参数:
protected void gridEmployees_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
// Get the ID of the record to update.
//int empID = (int)gridEmployees.DataKeys.[e.RowIndex];
// Get the reference to the list control.
DropDownList title = (DropDownList)(gridEmployees.Rows[e.RowIndex].FindControl("EditTitle"));
// Add it to the parameters.
e.NewValues.Add("TitleOfCourtesy", title.Text);
}
2.无命令列的编辑
目前见到的所有示例列都是使用CommandField自动产生编辑控件。现在,已经改用基于模板的方式了。值得思考的是应该如何加入自己的编辑控件。
其实很简单,所要做的知识在ItemTemplate内加入一个按钮并把它的CommandName设置为Eidt。这样他会自动触发编辑流程,产生专门的事件并把行带入编辑模式:
<ItemTemplate>
<b>
<%# Eval("EmployeeID") %> -
<%# Eval("TitleOfCourtesy") %> <%# Eval("FirstName") %>
<%# Eval("LastName") %>
</b>
<hr />
<small><i>
<%# Eval("Address") %><br />
<%# Eval("City") %>, <%# Eval("Country") %>,
<%# Eval("PostalCode") %><br />
<%# Eval("HomePhone") %></i>
<br /><br />
<%# Eval("Notes") %>
<br /><br />
<asp:LinkButton runat="server" Text="Edit" CommandName="Edit" ID="cmdEdit" />
</small>
</ItemTemplate>
在EditItemTemplate中还需要另外两个按钮,它们的CommandName分别是Update和Cancel:
<EditItemTemplate>
<b>
<%# Eval("EmployeeID") %> -
<asp:DropDownList runat="server" ID="EditTitle"
SelectedIndex='<%# GetSelectedTitle(Eval("TitleOfCourtesy")) %>'
Font-Names="Verdana" Font-Size="XX-Small"
DataSource='<%# TitlesOfCourtesy %>' />
<%# Eval("FirstName") %>
<%# Eval("LastName") %>
</b>
<hr />
<small><i>
<%# Eval("Address") %><br />
<%# Eval("City") %>, <%# Eval("Country") %>,
<%# Eval("PostalCode") %><br />
<%# Eval("HomePhone") %></i>
<br /><br />
<asp:TextBox Text='<%# Bind("Notes") %>' runat="server" id="textBox"Font-Names="Verdana" Font-Size="XX-Small" Height="40px"TextMode="MultiLine" Width="413px" />
<br /><br />
<asp:LinkButton runat="server" Text="Update"
CommandName="Update" ID="cmdUpdate" />
<asp:LinkButton runat="server" Text="Cancel"
CommandName="Cancel" ID="cmdCancel" />
</small>
</EditItemTemplate>
只是在按钮上设置CommandName属性时使用这些名字,GridView的编辑事件就会发生,数据源控件也会以相同的方式响应这在和在使用自动产生的编辑控件时是一致的