[ASP.NET]C1Webgrid中实现编辑和计算
在WebGrid/GridView等控件中,经常遇到需要编辑列,然后计算的应用,以下是一些经验。
应用需求
下面的代码可能与实际不符,因使用的本来是C1WebGrid和C1WebNumbericEdit。
1: <C1WebGrid:C1WebGrid ID="cwgRealSingle" runat="server"
2: AutoGenerateColumns="False" BackColor="White"
3: BorderStyle="Solid" BorderWidth="1px" BorderColor="ActiveBorder" CallbackOptions="Sorting" CellPadding="3"
4: Font-Names="Verdana" Font-Size="11px" Width="100%" Height="100%"
5: CssClass="gridView" onitemcreated="cwgRealSingle_ItemCreated"
6: oneditingcommand="cwgRealSingle_EditingCommand"
7: oncancelingcommand="cwgRealSingle_CancelingCommand"
8: onupdatingcommand="cwgRealSingle_UpdatingCommand">
9: <footerstyle backcolor="White" />
10: <selecteditemstyle backcolor="#669999" forecolor="White" BorderColor="AliceBlue" BorderWidth="1px" BorderStyle="Solid"/>
11: <Columns>
12: <C1WebGrid:C1TemplateColumn Visible="False" HeaderText="项目代码">
13: <ItemTemplate>
14: <asp:Label ID="lblItemName" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.itemname") %>' Width="80%"></asp:Label>
15: </ItemTemplate>
16: </C1WebGrid:C1TemplateColumn>
17: <C1WebGrid:C1BoundColumn DataField="workProcId" Visible="False" HeaderText="工序名称"></C1WebGrid:C1BoundColumn>
18: <C1WebGrid:C1BoundColumn DataField="workprocname" HeaderText="工序名称"
19: RowMerge="Free" ReadOnly="True"></C1WebGrid:C1BoundColumn>
20: <C1WebGrid:C1TemplateColumn HeaderText="计划产量" RowMerge="Restricted">
21: <EditItemTemplate>
22: <c1i:c1webnumericedit id="txtOutput" runat="server" width="92%" updownalign="None" text='<%# DataBinder.Eval(Container, "DataItem.Output") %>'
23: maxvalue="1E+28" height="22px" __designer:wfdid="w2" OnClientTextChanged="calcTotal(this);" ></c1i:c1webnumericedit>
24: </EditItemTemplate>
25: <ItemTemplate>
26: <asp:Label ID="lblOutput" runat="server" Width ="80%" Text='<%# DataBinder.Eval(Container, "DataItem.Output") %>'></asp:Label>
27: </ItemTemplate>
28: </C1WebGrid:C1TemplateColumn>
29: <C1WebGrid:C1BoundColumn DataField="energyid" HeaderText="能介代码" Visible="False"></C1WebGrid:C1BoundColumn>
30: <C1WebGrid:C1BoundColumn DataField="energyname" HeaderText="能介名称"
31: ReadOnly="True"></C1WebGrid:C1BoundColumn>
32: <C1WebGrid:C1BoundColumn DataField="keyname" HeaderText="属性代码" Visible="False"></C1WebGrid:C1BoundColumn>
33: <C1WebGrid:C1BoundColumn DataField="Propertyname" HeaderText="属性"
34: ReadOnly="True"></C1WebGrid:C1BoundColumn>
35: <C1WebGrid:C1BoundColumn DataField="Compute_Consingel" DataFormatString="{0:0.00}"
36: HeaderText="推荐单耗" ReadOnly="True">
37: </C1WebGrid:C1BoundColumn>
38: <C1WebGrid:C1TemplateColumn HeaderText="修正单耗">
39: <EditItemTemplate>
40: <table>
41: <tr>
42: <td>
43: <asp:DropDownList ID="ddlConsumpt" runat="server" OnSelectedIndexChanged="ddlConsumpt_SelectedIndexChanged" AutoPostBack="true" Width="120px"></asp:DropDownList>
44: </td>
45: <td>
46: <c1i:c1webnumericedit id="txtConsumpt" runat="server" width="92%" updownalign="None" text='<%# DataBinder.Eval(Container, "DataItem.Plan_Consingel") %>'
47: maxvalue="1E+28" height="22px" __designer:wfdid="w2" OnClientTextChanged="calcTotal(this);" ></c1i:c1webnumericedit>
48: </td>
49: </tr>
50: </table>
51: </EditItemTemplate>
52: <ItemTemplate>
53: <asp:Label ID="lblPlan_cons" runat="server" Width ="80%" Text='<%# DataBinder.Eval(Container, "DataItem.Plan_Consingel") %>'></asp:Label>
54: </ItemTemplate>
55: </C1WebGrid:C1TemplateColumn>
56: <C1WebGrid:C1TemplateColumn HeaderText="计划量">
57: <EditItemTemplate>
58: <asp:TextBox ID="txtValues" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.Values") %>' Width="80%"></asp:TextBox>
59: </EditItemTemplate>
60: <ItemTemplate>
61: <asp:Label ID="lblValues" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.Values") %>' Width="80%"></asp:Label>
62: </ItemTemplate>
63: </C1WebGrid:C1TemplateColumn>
64: <C1WebGrid:C1EditCommandColumn EditText="修改" HeaderText="修改" CancelText="取消"
65: UpdateText="保存">
66: </C1WebGrid:C1EditCommandColumn>
67: </Columns>
68: <itemstyle verticalalign="Middle" horizontalalign="Center" BorderColor="Control" />
69: <pagerstyle backcolor="White" horizontalalign="Left" />
70: <headerstyle font-bold="True" forecolor="White" verticalalign="Middle" cssclass="gt" />
71: </C1WebGrid:C1WebGrid>
触发计算
在C1WebGrid中,可直接使用C1WebNumbericEdit控件的OnClientValueChanged事件,代码如下:
1: OnClientTextChanged="calcTotal(this);"
处理的JS脚本如下:
1: <script type="text/javascript">
2: function calcTotal(source )
3: {
4: var row_id = source.id.substr(0, source.id.lastIndexOf('_') + 1);
5: var textbox1 = document.getElementById(row_id + 'txtOutput');
6: var textbox2 = document.getElementById(row_id + 'txtConsumpt');
7: var label = document.getElementById(row_id + 'txtValues');
8: label.value = Number(textbox1.value) * Number(textbox2.value);
9: }
10: </script>
否则的话,需要处理TextBox的客户端事件(实际上此时TextBox已经被替换为Input标签了,也只能使用Input的事件,据说可以直接使用OnTextChanged事件),即处理GridView的RowDataBound事件。下面的代码是在编辑时,如果需要为下拉框绑定值时使用的。如果只是添加TextBox的值改变,可以如下面注释的代码一样,添加txtUnit.Attributes.Add(“onblur”,"'onblur”)。
1:
2: protected void cwgRealSingle_ItemCreated(object sender, C1ItemEventArgs e)
3: {
4: if (e.Item.ItemType == C1.Web.C1WebGrid.C1ListItemType.EditItem)
5: {
6: DropDownList ddl = e.Item.Cells[9].FindControl("ddlConsumpt") as DropDownList;
7: if (ddl == null) return;
8:
9: // 添加事件
10: //ddl.Attributes.Add("onchange","changeddl(this);");
11:
12: // 添加下拉框数据和绑定默认值
13: PlanComputeV compute = e.Item.DataItem as PlanComputeV;
14:
15: BindDropDown(ddl, compute);
16: }
17: }
在下拉框的处理事件中,因为SelectedIndexChanged事件只有在点击保存按钮中提交回发时才会触发,为了简便,使用了以下方法:
1. 设置C1WebGrid的AutoPostBack事件为True;
2. 为了保存滚动条位置,设置了页面的MaintainScrollPositionOnPostback为True。
这样下拉的时候会有明显的刷新页面操作,在数据量大或者网络差得情况下性能很成问题,有待完善。可以用Updatepanel包含GridView,临时解决。
遗留问题
- RowDataBound和RowCreated事件的区别?
- 对于非编辑字段,需要将Readonly设置为True才能在编辑时查看数据?
- 在VS2008中,RowUpdating事件中无法取到Label的值(TextBox等可以),使用Request.Form也不能获取,据说VS2005中可以?