<1>Web窗體准備:
1,VS2017-->文件-->新建-->項目-->ASP.net空網站-->設置好項目名和文件保存的位置-->打開解決方案資源管理器-->右鍵項目名-->添加-->添加新項-->選擇Web窗體-->確定。
[注]:使用ASP.net空網站的目的是沒有其他框架過多的束縛,有利於調試核心的程序部分;Web窗體默認名為Default.aspx,可以改也可以不改。
2,打開Default.aspx,使用工具箱中控件或者元素標簽,移到設計面板中。因為打開Default.aspx文件后,代碼面板區左下角會有三個不同的選項:設計/拆分/源。最好使用拆分,這樣設計的內容和源代碼內容都可以同步看到。
下面是我的源代碼,根據源代碼來講設計意圖:
[注:]我使用了兩個HTML的table元素標簽,主要是用來裝具體的響應控件,比如按鈕,TextBox,Table(這個Table就是用來記錄要存放到數據庫中的多條數據)HTML的table元素跟Table控件是有區別的。GridView主要用於顯示數據庫表中的內容,以及每次插入之后
數據庫的內容。
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>
<%--<!DOCTYPE html>--%>
<%--替換成下面這句,是用於下面的table元素中的cellspacing,cellpadding屬性,因為XHTML5中這連個不是table的屬性--%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> </head> <body> <form id="form1" runat="server" method="post"> <table style="width:511px;margin:0 auto;text-align:center"> <tr> <td colspan="3" style="height:86px">添加多條數據<asp:TextBox ID="TextDubugForUse" runat="server" Width="303px"></asp:TextBox> </td> </tr> <tr> <td colspan="3"> <asp:Table ID="Table1" runat="server" Width="195px"> </asp:Table> </td> </tr> <tr> <td colspan="3" > <table cellspacing="0"cellpadding="0" style="width:250px;margin:0 auto"> <tr style="height:22px"> <td colspan="2"> <asp:Button ID="btnData" runat="server" Font-Size="9pt" Height="21px" Text="添加數據" OnClick="btnData_Click" EnableViewState="False"/> </td> <td> <asp:Button ID="brnAddTxt" runat="server" Text="添加單元格" OnClick="brnAddTxt_Click" /> </td> </tr> <tr> <td colspan="3" rowspan="1" style="height:21px"> <asp:GridView ID="GridView1" runat="server"> </asp:GridView> </td> </tr> </table> </td> </tr> </table> </form> </body> </html>
這是布局后的樣子:
<2>編寫響應事件的代碼
1,首先是Page_Load()函數,也就是第一次加載Default.aspx頁面,所要做的事情。
protected void Page_Load(object sender, EventArgs e) { string constr = ConfigurationManager.ConnectionStrings["pubsConString"].ConnectionString; SqlConnection con = new SqlConnection(constr); SqlDataAdapter da = new SqlDataAdapter("select * from agent_bak",con); DataSet ds = new DataSet(); da.Fill(ds); GridView1.DataSource = ds; GridView1.DataBind(); if (Convert.ToInt16(ViewState["Count"])!= 0)//if 中的判斷語句也可以寫成ViewState["Count"]!=null
{ for (int i = 0; i < Convert.ToInt16(ViewState["Count"]); i++) { AddTextBox(); } } else { btnData.Enabled = false; } }
這個函數包含的內容有:
a,通過配置文件中的內容來設置數據庫連接語句。
b,將數據庫中具體表的內容顯示到GridView控件中
c,使用ViewState(這個問題要跟后面的按鈕響應事件聯系起來后面再講)
a,配置文件中的內容:
<connectionStrings> <add name="pubsConString" connectionString="Initial Catalog=sales;Persist Security Info=True;User ID=sa;password="23456789" providerName="System.Data.SqlClient"/> </connectionStrings>
其中password為你的SQLserver數據庫的密碼,我的數據庫名稱為sales,里面有一個agent_bak表,表的字段情況為:
b,Page_Load()函數一運行,也就是用瀏覽器打開這個頁面,就會將數據庫sales中的agent_bak表中的所有內容顯示在GridView控件上。
至於if else語句中的內容,要先將清后面的內容才能講清。
2,編寫AddTextBox()函數,用於記錄要插入數據庫的內容,這里設計的是一個Table控件,只要調用這個函數,那么這個Table控件就會新增一個單元格,而這個單元格里面就可以寫入要存入數據庫的記錄。
public void AddTextBox() {
//要插入的數據 TableRow tr = new TableRow(); TableCell c1 = new TableCell(); TextBox txt = new TextBox(); txt.ID = "tb" + Table1.Rows.Count; txt.Font.Size = FontUnit.Point(9);
//提示信息 TableCell c2 = new TableCell(); Label lb = new Label(); lb.ID = "lb" + Table1.Rows.Count; lb.Width = 50; lb.Text = "數據" + (Table1.Rows.Count + 1); c2.Controls.Add(lb); c1.Controls.Add(txt); tr.Cells.Add(c2); tr.Cells.Add(c1); Table1.Rows.Add(tr);
//Table-->tr-->Cells-->每個Cell }
3, 添加單元格響應事件:
protected void brnAddTxt_Click(object sender, EventArgs e) { AddTextBox(); ViewState["Count"] = Convert.ToInt16(ViewState["Count"]) + 1; btnData.Enabled = true; }
a,第一先把Table控件單元格畫一個。
b,這里我就可以講Page_Load()函數中的ViewState的意圖:
我把ViewState理解成記錄狀態的一個字典。剛開始Page_Load()執行的時候ViewState["Count"]值為null,也就是Convert.ToInt16(ViewState["Count"])為0,那么Page_Load()的if中的語句不執行,else中的語句執行btnData.Enabled = false,那么現在一方面沒有畫出增加的單元格,另一方面也無法點擊添加數據按鈕。
當點擊增加單元格按鈕后,Table控件增加了一個單元格。Convert.ToInt16(ViewState["Count"])值增加一,如圖:
這里因為點擊控件按鈕之后,那么會重新調用Page_Load()函數,那么GridView會更新獲得數據庫表中的內容。由於Convert.ToInt16(ViewState["Count"])=1,那么AddTextBox()會從新繪制,而不會因為重新刷新頁面到時,這個新增的單元格消失掉,從而保證能寫入數據。
寫入數據之后,Table.Rows.Count就會加1。如果在點擊添加單元格,Table控件再增加了一個單元格,那么Convert.ToInt16(ViewState["Count"])=2,我們按了按鈕,肯定應該所有重新繪制,但是Page_Load()函數中有(ViewState["Count"]),這里調用兩次AddTextBox(),就保證了能記錄第二個數據。
這里我就體會了這個ViewState是多么巧妙,還有那個Table控件。每次記錄時候,都會是記錄在這個Table的新的行里,這就為后面循環插入數據庫做了充分准備。
4,最后我們看看那個添加到數據庫中的函數,也就是循環插入。這個函數比較麻煩的地方是寫Insert語句中的引號問題。
protected void btnData_Click(object sender, EventArgs e) { string constr = ConfigurationManager.ConnectionStrings["pubsConString"].ConnectionString; SqlConnection con = new SqlConnection(constr); con.Open(); SqlCommand cmd; string cmdTxt; for (int i = 0; i < Table1.Rows.Count; i++) { string b = ""; string[] a = ((TextBox)Table1.Rows[i].FindControl("tb" + i)).Text.Split(','); for (int j = 0; j < a.Length - 1; j++) { b += "'" + a[j] + "'" + ","; } b += "'" + a[a.Length - 1] + "'"; //cmdTxt = "insert into agent_bak(aid,aname,city,per) values('" + ((TextBox)Table1.Rows[i].FindControl("tb" + i)).Text.ToString() + "')"; cmdTxt = "insert into agent_bak(aid,aname,city,per) values(" + b+ ")"; cmd = new SqlCommand(cmdTxt,con); cmd.ExecuteNonQuery(); } con.Close(); //Response.Write("<script language=javascript>alert('插入數據成功')</script>"); }
到此結束。