GridView控件只让某列可以编辑,并在后台获取值的方法
需求是这样的:
使用GridView绑定数据源显示数据,然后其中的价格和报价总数要窗体一加载就是编辑模式,并且修改里面的值点击保存更改可以成功修改数据库中对应的字段。
一开始我想的是使用GridView自带的RowEditing:开始编辑事件,后台代码是这样的:
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
GridView1.EditIndex = e.NewEditIndex; // 设置开启编辑
bind(); // 重新绑定 GridView
}
e.NewEditIndex是将列索引传递到后台(从0开始),这样就能实现编辑效果,但是需求是窗体一加载就要实现编辑状态,而且是所有行的某两列都要实现编辑状态,使用GridView1.EditIndex只能实现一行的编辑状态,可以控制那两列,只需要将不用编辑状态的列隐藏:控件名.Rows[e.NewEditIndex].Cells[列].Enabled = false;
显然在这里不能用控件自带的编辑方法去实现效果,那么这个时候就轮到模板列出场了,话不多说,直接看代码:
前台代码:
<asp:Button ID="btnSave" runat="server" Text="保存更改" OnClick="btnSave_Click" />
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:BoundField DataField="SaleOrderDetailID" HeaderText="明细编号" ReadOnly="true" SortExpression="SaleOrderDetailID" />
<asp:BoundField DataField="ProductName" HeaderText="产品名称" ReadOnly="true" SortExpression="ProductCode" />
<asp:BoundField DataField="ProductUnit" HeaderText="单位" ReadOnly="true" SortExpression="ProductUnit" />
<asp:BoundField DataField="CurrencyName" HeaderText="币种" ReadOnly="true" SortExpression="CurrencyName" />
<%--模板列(价格)--%>
<asp:TemplateField ItemStyle-Width="50">
<HeaderTemplate>
<asp:Label ID="Label1" runat="server" Text="价格"></asp:Label>
</HeaderTemplate>
<ItemTemplate>
<asp:TextBox ID="txtPrice" runat="server" Text='<%# Eval("Price") %>'></asp:TextBox>
<asp:RegularExpressionValidator ID="RegularExpressionValidator1" ControlToValidate="txtPrice" ValidationExpression="^[-+]?(([0-9]+)([.]([0-9]+))?|([.]([0-9]+))?)$" runat="server" ErrorMessage="格式不正确!" ForeColor="Red"></asp:RegularExpressionValidator>
</ItemTemplate>
</asp:TemplateField>
<%--模板列(报价总数)--%>
<asp:TemplateField ItemStyle-Width="50">
<HeaderTemplate>
<asp:Label ID="Label2" runat="server" Text="报价总数"></asp:Label>
</HeaderTemplate>
<ItemTemplate>
<asp:TextBox ID="txtQuantity" runat="server" Text='<%# Eval("Quantity") %>'></asp:TextBox>
<asp:RegularExpressionValidator ID="RegularExpressionValidator2" ControlToValidate="txtQuantity" ValidationExpression="^[-+]?(([0-9]+)([.]([0-9]+))?|([.]([0-9]+))?)$" runat="server" ErrorMessage="格式不正确!" ForeColor="Red"></asp:RegularExpressionValidator>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="RQuantity" HeaderText="剩余数量" ReadOnly="true" SortExpression="RQuantity" />
<asp:BoundField DataField="Remark" HeaderText="备注" ReadOnly="true" SortExpression="Remark"></asp:BoundField>
<asp:ButtonField CommandName="Edit" Text="编辑"></asp:ButtonField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnkDelete" runat="server" CausesValidation="false" CommandName="Delete"
OnClientClick="return confirm('确认要删除吗?');" Text="删除"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
其实模板列就是在GridView控件中添加一个TemplateField标签,然后这里面有头部HeaderTemplate,中间部分ItemTemplate,做到这里的时候我就发现模板列的用法跟Repeat中的用法一模一样,然后我们在头部用一个Label控件写上标题,中间部分就是我们要显示的编辑状态,就是一个TextBox控件,里面的Text属性绑定字段 Text=’<%# Eval(“Price”) %>’,这里要注意是单引号’’,习惯性双引号就会报错,外面是单引号,里面才是双引号加字段。
在后台绑定数据源后就可以显示效果了,就是一开始的那张图片,但是还没实际效果,修改TextBox的值数据库里面还是不会改变,这里的难点就在于如何在后台获取到文本框的值,在这里我们就得理解一个概念,如果文本框在GridView控件里面,那么在后台是无法通过ID来获取值的,因为GridView显示数据是通过循环来显示数据的,后台代码:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//绑定数据源
this.GridView1.DataSource = Manage.BLL.sale_SaleOtherFee.Select();
this.GridView1.DataBind();
}
}
protected void btnSave_Click(object sender, EventArgs e)
{
//首先声明变量来存放值
//这里的话你可以根据你的需要来,我这里是价格Price,报价总数Quantity,明细编号OrderDetilID,只需三个变量即可
string OrderDetilID;
string Price;
string Quantity;
//GridView1.Rows.Count获取当前数据行数,已知循环次数用for循环
for (int i = 0; i < GridView1.Rows.Count; i++)
{
//将明细编号赋值给变量OrderDetilID
OrderDetilID = GridView1.Rows[i].Cells[0].Text;
//这里是获取前台文本框里面的值
//(控件名.Rows[i].FindControl("文本框ID") as TextBox).Text
Price = (GridView1.Rows[i].FindControl("txtPrice") as TextBox).Text;
Quantity = (GridView1.Rows[i].FindControl("txtQuantity") as TextBox).Text;
//我们前面加了正则表达式,所以不用担心格式不对,直接修改就可以了
//调用方法修改数据
if (Manage.BLL.sale_SaleOrderDetail.Update(OrderDetilID, Price, Quantity))
{
//修改成功!
}
}
Response.Write("<script>alert('修改成功!')</script>");
//刷新页面代码
Response.AddHeader("Refresh", "0");
}
**总结:Repeat控件还是好用一点,Repeat里面就只有一个基本的框架,别的东西都可以自己加,可以很好的根据自己的需求来,而使用GridView对数据操作就必须按照它的规则来,否则就无法获取到数据或者报错,今天这个需求卡了我好久,网上又没有详细的案例,于是我综合了三篇文章的知识才解决掉这个需求,希望这篇文章可以帮助到你!