主表和明细表输入在B/S下一直不尽人意,本人在以前开源的CRM中提供了通过session实现主表明细表跟C/S效果相近的功能, 考虑到服务器压力和资源占用情况,目前研究出一种通过viewstate来实现的方法.
具体代码和实现,请下载EasyPlat.net 4.5
萧 QQ:775066802
技术支持QQ群:293588155
EMAIL:[email protected]
EasyPlat.net 当前版本 V4.5
前台实现:
<Columns>
<asp:BoundField DataField="RowNumber" HeaderText="序号" ItemStyle-HorizontalAlign="Center" ItemStyle-Width="40px" />
<asp:TemplateField HeaderText="产品编码">
<ItemTemplate>
<asp:TextBox ID="txtProductCode" runat="server" OnTextChanged="txtProductCode_TextChanged" AutoPostBack="true"
CssClass="DetailCss" Width="105px" MaxLength="13"></asp:TextBox>
</ItemTemplate>
<FooterStyle HorizontalAlign="Left" />
<FooterTemplate>
<asp:Button ID="ButtonAdd" runat="server" Text="增新行" OnClick="ButtonAdd_Click" />
</FooterTemplate>
<ItemStyle Width="138px" />
</asp:TemplateField>
<asp:TemplateField HeaderText="产品型号">
<ItemTemplate>
<asp:TextBox ID="txtProductType" runat="server" CssClass="DetailCss" Width="130px" MaxLength="100"></asp:TextBox>
</ItemTemplate>
<ItemStyle Width="130px" />
</asp:TemplateField>
<asp:TemplateField HeaderText="名称">
<ItemTemplate>
<asp:TextBox ID="txtName" runat="server" CssClass="DetailCss" Width="180px" MaxLength="100"></asp:TextBox>
</ItemTemplate>
<ItemStyle Width="180px" />
</asp:TemplateField>
<asp:TemplateField HeaderText="规格">
<ItemTemplate>
<asp:TextBox ID="txtSpec" runat="server" CssClass="DetailCss" Width="90px" MaxLength="100"></asp:TextBox>
</ItemTemplate>
<ItemStyle Width="90px" />
</asp:TemplateField>
<asp:TemplateField HeaderText="价格">
<ItemTemplate>
<asp:TextBox ID="txtPrice" runat="server" CssClass="DetailCss" Width="89px" MaxLength="10"></asp:TextBox>
</ItemTemplate>
<ItemStyle Width="90px" />
</asp:TemplateField>
<asp:TemplateField HeaderText="数量">
<ItemTemplate>
<asp:TextBox ID="txtNum" runat="server" OnTextChanged="txtNum_TextChanged" AutoPostBack="true" CssClass="DetailCss" Width="65px" MaxLength="10"></asp:TextBox>
</ItemTemplate>
<ItemStyle Width="66px" />
</asp:TemplateField>
<asp:TemplateField HeaderText="单位">
<ItemTemplate>
<asp:TextBox ID="txtUnit" runat="server" CssClass="DetailCss" Width="59px" MaxLength="6"></asp:TextBox>
</ItemTemplate>
<ItemStyle Width="60px" />
</asp:TemplateField>
<asp:TemplateField HeaderText="小计">
<ItemTemplate>
<asp:TextBox ID="txtSubTotal" runat="server" CssClass="DetailCss" Width="89px" MaxLength="10"></asp:TextBox>
</ItemTemplate>
<ItemStyle Width="90px" />
</asp:TemplateField>
<asp:TemplateField HeaderText="描述">
<ItemTemplate>
<asp:TextBox ID="txtProfile" runat="server" CssClass="DetailCss" Width="260px" MaxLength="200"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText=""></asp:TemplateField>
<asp:CommandField ShowDeleteButton="True" ControlStyle-Width="60px" />
</Columns>
后台代码:
private DataTable CreateTable()
{
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("RowNumber", typeof(string)));
dt.Columns.Add(new DataColumn("ProductCode", typeof(string)));
dt.Columns.Add(new DataColumn("ProductType", typeof(string)));
dt.Columns.Add(new DataColumn("Name", typeof(string)));
dt.Columns.Add(new DataColumn("Spec", typeof(string)));
dt.Columns.Add(new DataColumn("Price", typeof(string)));
dt.Columns.Add(new DataColumn("Num", typeof(string)));
dt.Columns.Add(new DataColumn("Unit", typeof(string)));
dt.Columns.Add(new DataColumn("SubTotal", typeof(string)));
dt.Columns.Add(new DataColumn("Profile", typeof(string)));
DataRow dr = dt.NewRow();
dr["RowNumber"] = 1;
dr["ProductCode"] = string.Empty;
dr["ProductType"] = string.Empty;
dr["Name"] = string.Empty;
dr["Spec"] = string.Empty;
dr["Price"] = string.Empty;
dr["Num"] = string.Empty;
dr["Unit"] = string.Empty;
dr["SubTotal"] = string.Empty;
dr["Profile"] = string.Empty;
dt.Rows.Add(dr);
return dt;
}
private void FirstGridViewRow(DataTable dt)
{
ViewState["CurrentTable"] = dt;
gvDetail.DataSource = dt;
gvDetail.DataBind();
if (!string.IsNullOrWhiteSpace(code))
SetPreviousData();
TextBox txn = (TextBox)gvDetail.Rows[0].Cells[1].FindControl("txtProductCode");
txn.Focus();
Button btnAdd = (Button)gvDetail.FooterRow.Cells[1].FindControl("ButtonAdd");
Page.Form.DefaultFocus = btnAdd.ClientID;
}
protected void ButtonAdd_Click(object sender, EventArgs e)
{
AddNewRow();
}
private void AddNewRow()
{
int rowIndex = 0;
if (ViewState["CurrentTable"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
DataRow drCurrentRow = null;
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
TextBox txtProductCode = (TextBox)gvDetail.Rows[rowIndex].Cells[1].FindControl("txtProductCode");
TextBox txtProductType = (TextBox)gvDetail.Rows[rowIndex].Cells[2].FindControl("txtProductType");
TextBox txtName = (TextBox)gvDetail.Rows[rowIndex].Cells[3].FindControl("txtName");
TextBox txtSpec = (TextBox)gvDetail.Rows[rowIndex].Cells[4].FindControl("txtSpec");
TextBox txtPrice = (TextBox)gvDetail.Rows[rowIndex].Cells[5].FindControl("txtPrice");
TextBox txtNum = (TextBox)gvDetail.Rows[rowIndex].Cells[6].FindControl("txtNum");
TextBox txtUnit = (TextBox)gvDetail.Rows[rowIndex].Cells[7].FindControl("txtUnit");
TextBox txtSubTotal = (TextBox)gvDetail.Rows[rowIndex].Cells[7].FindControl("txtSubTotal");
TextBox txtProfile = (TextBox)gvDetail.Rows[rowIndex].Cells[8].FindControl("txtProfile");
// RadioButtonList RBLGender = (RadioButtonList)gvDetail.Rows[rowIndex].Cells[4].FindControl("RBLGender");
// DropDownList DrpQualification = (DropDownList)gvDetail.Rows[rowIndex].Cells[5].FindControl("drpQualification");
dtCurrentTable.Rows[i - 1]["ProductCode"] = txtProductCode.Text;
dtCurrentTable.Rows[i - 1]["ProductType"] = txtProductType.Text;
dtCurrentTable.Rows[i - 1]["Name"] = txtName.Text;
dtCurrentTable.Rows[i - 1]["Spec"] = txtSpec.Text;
dtCurrentTable.Rows[i - 1]["Price"] = txtPrice.Text;
dtCurrentTable.Rows[i - 1]["Num"] = txtNum.Text;
dtCurrentTable.Rows[i - 1]["Unit"] = txtUnit.Text;
dtCurrentTable.Rows[i - 1]["SubTotal"] = txtSubTotal.Text;
dtCurrentTable.Rows[i - 1]["Profile"] = txtProfile.Text;
rowIndex++;
}
drCurrentRow = dtCurrentTable.NewRow();
drCurrentRow["RowNumber"] = rowIndex + 1;
dtCurrentTable.Rows.Add(drCurrentRow);
ViewState["CurrentTable"] = dtCurrentTable;
gvDetail.DataSource = dtCurrentTable;
gvDetail.DataBind();
TextBox txn = (TextBox)gvDetail.Rows[rowIndex].Cells[1].FindControl("txtProductCode");
txn.Focus();
}
}
else
{
Response.Write("ViewState is null");
}
SetPreviousData();
}
private void SetPreviousData()
{
int rowIndex = 0;
if (ViewState["CurrentTable"] != null)
{
DataTable dt = (DataTable)ViewState["CurrentTable"];
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
TextBox txtProductCode = (TextBox)gvDetail.Rows[rowIndex].Cells[1].FindControl("txtProductCode");
TextBox txtProductType = (TextBox)gvDetail.Rows[rowIndex].Cells[2].FindControl("txtProductType");
TextBox txtName = (TextBox)gvDetail.Rows[rowIndex].Cells[3].FindControl("txtName");
TextBox txtSpec = (TextBox)gvDetail.Rows[rowIndex].Cells[4].FindControl("txtSpec");
TextBox txtPrice = (TextBox)gvDetail.Rows[rowIndex].Cells[5].FindControl("txtPrice");
TextBox txtNum = (TextBox)gvDetail.Rows[rowIndex].Cells[6].FindControl("txtNum");
TextBox txtUnit = (TextBox)gvDetail.Rows[rowIndex].Cells[7].FindControl("txtUnit");
TextBox txtSubTotal = (TextBox)gvDetail.Rows[rowIndex].Cells[8].FindControl("txtSubTotal");
TextBox txtProfile = (TextBox)gvDetail.Rows[rowIndex].Cells[8].FindControl("txtProfile");
gvDetail.Rows[i].Cells[0].Text = Convert.ToString(i + 1);
txtProductCode.Text = dt.Rows[i]["ProductCode"].ToString();
txtProductType.Text = dt.Rows[i]["ProductType"].ToString();
txtName.Text = dt.Rows[i]["Name"].ToString();
txtSpec.Text = dt.Rows[i]["Spec"].ToString();
txtPrice.Text = dt.Rows[i]["Price"].ToString();
txtNum.Text = dt.Rows[i]["Num"].ToString();
txtUnit.Text = dt.Rows[i]["Unit"].ToString();
txtSubTotal.Text = dt.Rows[i]["SubTotal"].ToString();
txtProfile.Text = dt.Rows[i]["Profile"].ToString();
rowIndex++;
}
}
}
}
protected void gvDetail_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
SetRowData();
if (ViewState["CurrentTable"] != null)
{
DataTable dt = (DataTable)ViewState["CurrentTable"];
DataRow drCurrentRow = null;
int rowIndex = Convert.ToInt32(e.RowIndex);
if (dt.Rows.Count > 1)
{
dt.Rows.Remove(dt.Rows[rowIndex]);
drCurrentRow = dt.NewRow();
ViewState["CurrentTable"] = dt;
gvDetail.DataSource = dt;
gvDetail.DataBind();
for (int i = 0; i < gvDetail.Rows.Count - 1; i++)
{
gvDetail.Rows[i].Cells[0].Text = Convert.ToString(i + 1);
}
SetPreviousData();
}
}
}
private void SetRowData()
{
int rowIndex = 0;
if (ViewState["CurrentTable"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
DataRow drCurrentRow = null;
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
TextBox txtProductCode = (TextBox)gvDetail.Rows[rowIndex].Cells[1].FindControl("txtProductCode");
TextBox txtProductType = (TextBox)gvDetail.Rows[rowIndex].Cells[2].FindControl("txtProductType");
TextBox txtName = (TextBox)gvDetail.Rows[rowIndex].Cells[3].FindControl("txtName");
TextBox txtSpec = (TextBox)gvDetail.Rows[rowIndex].Cells[4].FindControl("txtSpec");
TextBox txtPrice = (TextBox)gvDetail.Rows[rowIndex].Cells[5].FindControl("txtPrice");
TextBox txtNum = (TextBox)gvDetail.Rows[rowIndex].Cells[6].FindControl("txtNum");
TextBox txtUnit = (TextBox)gvDetail.Rows[rowIndex].Cells[7].FindControl("txtUnit");
TextBox txtSubTotal = (TextBox)gvDetail.Rows[rowIndex].Cells[7].FindControl("txtSubTotal");
TextBox txtProfile = (TextBox)gvDetail.Rows[rowIndex].Cells[8].FindControl("txtProfile");
dtCurrentTable.Rows[i - 1]["ProductCode"] = txtProductCode.Text;
dtCurrentTable.Rows[i - 1]["ProductType"] = txtProductType.Text;
dtCurrentTable.Rows[i - 1]["Name"] = txtName.Text;
dtCurrentTable.Rows[i - 1]["Spec"] = txtSpec.Text;
dtCurrentTable.Rows[i - 1]["Price"] = txtPrice.Text;
dtCurrentTable.Rows[i - 1]["Num"] = txtNum.Text;
dtCurrentTable.Rows[i - 1]["Unit"] = txtUnit.Text;
dtCurrentTable.Rows[i - 1]["SubTotal"] = txtSubTotal.Text;
dtCurrentTable.Rows[i - 1]["Profile"] = txtProfile.Text;
rowIndex++;
}
drCurrentRow = dtCurrentTable.NewRow();
drCurrentRow["RowNumber"] = rowIndex + 1;
ViewState["CurrentTable"] = dtCurrentTable;
//gvDetail.DataSource = dtCurrentTable;
//gvDetail.DataBind();
}
}
else
{
Response.Write("ViewState is null");
}
//SetPreviousData();
}
增加和更新按钮功能使用平台封装的方法:
bizSQL.InsertMainAndDetail("Cust_QuotationList", mainList, "Cust_QuotationDetail", detailList);
bizSQL.UpdateMainAndDetail("Cust_QuotationList", mainList, primaryKey, "Cust_QuotationDetail", detailList);
从此主表明细表不会让你头疼了