GridView新增功能圖文篇

補上一篇有圖片的「GridView新增功能」,以Visual Studio 2010來實作。

第一步:準備
  1. 新增專案 →「ASP.NET 空白 Web 應用程式」;

    新增專案
  2. 加入 → 新增項目 → Web Form → 名稱:「Default.aspx」;
  3. 切換至「設計」→ 拉入「GridView 及 SqlDataSource」;

    GridView + SqlDataSource
  4. 設定「SqlDataSource」,重點在sqlDataSource設定裡的「進階」必須產生Insert、Delete、Update等語法

以下範列使用Northwind資料庫中的Customers資料表。
<form id="form1" runat="server">
    <div>
        <asp:GridView ID="GridView1" runat="server">
        </asp:GridView>
        <br />
        <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
            ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
            DeleteCommand="DELETE FROM [Customers] WHERE [CustomerID] = @CustomerID" 
            InsertCommand="INSERT INTO [Customers] ([CustomerID], [CompanyName], [ContactName], [ContactTitle], [Address], [City], [Region], [PostalCode], [Country], [Phone], [Fax]) VALUES (@CustomerID, @CompanyName, @ContactName, @ContactTitle, @Address, @City, @Region, @PostalCode, @Country, @Phone, @Fax)" 
            SelectCommand="SELECT * FROM [Customers]" 
            UpdateCommand="UPDATE [Customers] SET [CompanyName] = @CompanyName, [ContactName] = @ContactName, [ContactTitle] = @ContactTitle, [Address] = @Address, [City] = @City, [Region] = @Region, [PostalCode] = @PostalCode, [Country] = @Country, [Phone] = @Phone, [Fax] = @Fax WHERE [CustomerID] = @CustomerID">
            <DeleteParameters>
                <asp:Parameter Name="CustomerID" Type="String" />
            </DeleteParameters>
            <InsertParameters>
                <asp:Parameter Name="CustomerID" Type="String" />
                <asp:Parameter Name="CompanyName" Type="String" />
                <asp:Parameter Name="ContactName" Type="String" />
                <asp:Parameter Name="ContactTitle" Type="String" />
                <asp:Parameter Name="Address" Type="String" />
                <asp:Parameter Name="City" Type="String" />
                <asp:Parameter Name="Region" Type="String" />
                <asp:Parameter Name="PostalCode" Type="String" />
                <asp:Parameter Name="Country" Type="String" />
                <asp:Parameter Name="Phone" Type="String" />
                <asp:Parameter Name="Fax" Type="String" />
            </InsertParameters>
            <UpdateParameters>
                <asp:Parameter Name="CompanyName" Type="String" />
                <asp:Parameter Name="ContactName" Type="String" />
                <asp:Parameter Name="ContactTitle" Type="String" />
                <asp:Parameter Name="Address" Type="String" />
                <asp:Parameter Name="City" Type="String" />
                <asp:Parameter Name="Region" Type="String" />
                <asp:Parameter Name="PostalCode" Type="String" />
                <asp:Parameter Name="Country" Type="String" />
                <asp:Parameter Name="Phone" Type="String" />
                <asp:Parameter Name="Fax" Type="String" />
                <asp:Parameter Name="CustomerID" Type="String" />
            </UpdateParameters>
        </asp:SqlDataSource>
    </div> 

第二步:GridView的新增環境

  1. 進入GridView的「編輯樣板」,選擇「EmptyDataTemplate」樣板;
  2. 拉一個DetailsView進去EmptyDataTemplate,資料來源選擇與GridView同一來源(sqlDataSouce);原因上面說了,我們要使用同一資料來源裡的Inster語法;
  3. 設定DetailsView的DefaultMode為「Insert」;

    Insert Mode
  4. 勾選DetailsView的「啟用插入」;

    DetailsView
  5. 進入DetailsView的「編輯欄位」,找「選取的欄位」最下方的「CommandField(中文版是:新增、插入、取消)」,把ShowCancelButton屬性設為「False」;因為在EmptyDataTemplate樣板中DetailsView取消按鈕不會有作用,留下會讓使用者把到「把柄」說:「你的程式有Bug!」

    DetailsView: 編輯欄位
    DetailsView : 取消CancelButton

第三步:GridView的新增觸發

  1. 選擇GridView的「編輯欄位」;
  2. 加入一個「ButtonField」,移動一下位置;設定ButtonField屬性Text:設定為「新增」;
  3. (重點)設定ButtonField屬性CommandName="GridInsert"(名稱請自訂)
GridView : 「新增」按鈕

第四步:讓GridView觸發事件,進入「EmptyDataTemplate樣板」

GridView : RowCommand事件

Protected Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles GridView1.RowCommand
    '中斷GridView與sqlDataSource的「綁定,Binding」中斷
    '讓GridView進入EmptyDataTemplate樣板
    If e.CommandName = "GridInsert" Then
        GridView1.DataSourceID = Nothing
    End If
End Sub

第五步:從EmptyDataTemplate樣板返回GridView

  1. (重點)在DetailsView中進入「編輯欄位」,選擇下方「CommandField(中文版是:新增、插入、取消)」,然後轉換為TemplateField欄位,回到DetailsView中;

    DetailsView : 轉換為樣版
  2. 選擇「編輯樣板」的「InsertItemTemplate」;新增作用在InsertItem樣板;

    DetailsView : 編輯樣板


    DetailsView : InsertItemTemplate
  3. 從「標準」工具中拉一個「Button」控制項(LinkButton或ImageButton也可以)到InsertItemTemplate樣板中;

    DetailsView : Back Link
  4. 設定Button屬性:Text為「Back GridView」;ID為「bntBack」;
  5. (重點)在Button控制項上點兩下,進入後置程式碼;

    Protected Sub bntBack_Click(ByVal sender As Object, ByVal e As EventArgs)
        Me.GridView1.DataSourceID = "SqlDataSource1"
    End Sub
    
  6. 結束所有樣板編輯

這樣就完成所有功能。

Demo:
GridView : 新增按鈕

DetailsView : 新增畫面

DetailsView : 新增資料

新增完成後按Back回到GridView

下載後,請自行修改Web.config中的連線字串。

28 則留言:

  1. 您好,我是直接使用DetialsView來做新增功能,將資料輸入資料庫(MS SQL)。但是輸入後,按確認會出現下列問題:
    不知道是哪裡出了問題


    接近 '/' 之處的語法不正確。
    描述: 在執行目前 Web 要求的過程中發生未處理的例外情形。請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。

    例外詳細資訊: System.Data.SqlClient.SqlException: 接近 '/' 之處的語法不正確。

    原始程式錯誤:

    在執行目前 Web 要求期間,產生未處理的例外狀況。如需有關例外狀況來源與位置的資訊,可以使用下列的例外狀況堆疊追蹤取得。

    堆疊追蹤:


    [SqlException (0x80131904): 接近 '/' 之處的語法不正確。]
    System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +1950890
    System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) +4846875
    System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) +194
    System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +2392
    System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +204
    System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +954
    System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +162
    System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) +175
    System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +137
    System.Web.UI.WebControls.SqlDataSourceView.ExecuteDbCommand(DbCommand command, DataSourceOperation operation) +386
    System.Web.UI.WebControls.SqlDataSourceView.ExecuteInsert(IDictionary values) +227
    System.Web.UI.DataSourceView.Insert(IDictionary values, DataSourceViewOperationCallback callback) +86
    System.Web.UI.WebControls.DetailsView.HandleInsert(String commandArg, Boolean causesValidation) +274
    System.Web.UI.WebControls.DetailsView.HandleEvent(EventArgs e, Boolean causesValidation, String validationGroup) +676
    System.Web.UI.WebControls.DetailsView.OnBubbleEvent(Object source, EventArgs e) +95
    System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +37
    System.Web.UI.WebControls.DetailsViewRow.OnBubbleEvent(Object source, EventArgs e) +113
    System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +37
    System.Web.UI.WebControls.LinkButton.OnCommand(CommandEventArgs e) +118
    System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument) +135
    System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
    System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
    System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +175
    System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1565

    回覆刪除
  2. 沒有原始Code,以上述資訊,我很難幫你。請將原始Code寄到kingkogn點bruce(at) gmail.com。

    回覆刪除
  3. 感謝分享,很棒的例子,也學到了許多;
    請問若是要將新增的按鈕放在 GridView 的外面,
    若遇到資料來源為 「空值」又該如何顯示資料?

    回覆刪除
  4. DataSource為空,那還有什麼"資料"。
    沒有資料,那要"顯示"什麼?

    回覆刪除
  5. 歐,抱歉了,我的意思是說,若是我的資料來源沒有資料(依據搜尋條件也許會這樣),所以 GridView 就沒有資料可以顯示,那這時,我還有辦法利用 GridView 新增資料嗎?

    回覆刪除
  6. GridView1.DataSourceID = Nothing

    GridView1.DataSourceID = ds

    1. 請了解Nothing與ds(假設ds資料為空)的差異,這給你去試。
    2. 一般就UI而言,我們不會把新增按鈕放在GridView之中,而是放在GrivView外的上/下方,上以範例只是圖個方便。

    回覆刪除
  7. 請問一下程式碼vb那邊如何轉成c#

    回覆刪除
  8. C#我不懂,我建議,去買MIS2000Lab的書,它的書VB與C#版本都有,這是從他的書中修改而來。

    或是去找他的Blog,我記得他有分享出來:http://www.dotblogs.com.tw/mis2000lab/,找「GridView」關鍵字即可。

    回覆刪除
  9. 抱歉, 我接照著步驟來做
    但運行的時候卻有error:

    Compilation Error

    Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.

    Compiler Error Message: CS0200: Property or indexer 'System.Web.UI.WebControls.CommandEventArgs.CommandName' cannot be assigned to -- it is read only

    Source Error:


    Line 5: protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
    Line 6: {
    Line 7: if (e.CommandName = "GridInsert")
    Line 8: {
    Line 9: this.GridView1.DataSourceID = null;

    請問該如何解決?

    回覆刪除
  10. 請把程式壓縮mail到 kingkong點bruce at gmail.com,我測試看看。

    回覆刪除
  11. 程式我收到了,看了之後有點…不知道要不要回。

    VB比較運算子:http://msdn.microsoft.com/zh-tw/library/215yacb6.aspx

    C#比較運算子:http://msdn.microsoft.com/zh-tw/library/ms173145.aspx

    答案在以上兩篇,先自己看看VB與C#有何差異。
    加油,我不喜歡直接給答案。

    回覆刪除
  12. 請問大大,如果要把detalviews 裏的欄位的textbox改為dropdownlist,如何去抓取裏的面的value,我用findcontrol都會有錯誤,謝謝

    回覆刪除
  13. Dear All

    1. 請把程式壓縮mail到 kingkong點bruce at gmail.com,然後再提問。
    2. 請說明你想的"做什麼事",請清楚表達。
    3. 沒有1、2點,我就不太會理你了。

    Dear 俊霖
    DetailsView 使用 SqlDataSource,應該不需要去抓去任何東西,它會自動去對應及Insert才對。

    回覆刪除
  14. 請問大大, 使用這個教學, 在Insert時, 我嘗試輸入空格, 出現錯誤! 請問該如何解決?

    回覆刪除
  15. 沒有資料就是空白,為什麼要輸入空格???請說明。

    1. 正常是做法是"自己去接接看",將你所放入的資料放入Inser語法中,是否造成不正常的語法。
    2. 資料庫欄位,是否是非null。

    回覆刪除
  16. 1. 不是語法錯誤, 我用了大大所提供的做法, 功能和大大所說的一樣。

    2.除primary key的field是非null, 其他都是可以null。

    sorry!可能是我表達了錯誤訊息,我想說的是在insert時輸入空格是想測試能否防止insert error(除了非null的欄位),測試後出現錯誤。所以想請問有沒有解決方法?

    回覆刪除
  17. 你這是資料庫觀念問題與ASP.NET無關:
    http://msdn.microsoft.com/zh-tw/library/ms174335(SQL.90).aspx

    1. 我們看「VALUES」這一段,反正要有值,但「空格」是值嗎,請問空格的資料型別是?
    2. 我們看「備註」中「插入資料列的規則」這一段,預設是會去除尾端空格,那又只輸入空格(不管幾個),那不就跟沒輸入一樣?

    3. 以上程式沒有進行「資料驗證處理」,這部份必須由你自行處理,先確保資料的安全性及正確性,你不先處理當然有很大機會出現錯誤訊息。明明是要連入字串,但你確打123,還不是一樣。處理完,然後才是開始進行資料庫動作。

    資料庫很笨,你給什麼我就吃什麼,有問題就吐一堆Error。出現錯誤訊息事小,被攻擊事大。

    So, 你不應該讓「空格」與資料庫有任何關係。

    回覆刪除
  18. 設定「SqlDataSource」,重點在sqlDataSource設定裡的「進階」必須產生Insert、Delete、Update等語法
    這個方法我不懂 我在進階裡,找不到產生insert的語法怎麼使用?

    回覆刪除
    回覆
    1. 設定「SqlDataSource」,重點在sqlDataSource設定裡的「進階」必須產生Insert、Delete、Update等語法..
      這是基本的精靈設定,建議您買mis2000的書來看或上他的課,謝謝

      刪除
  19. 設定「SqlDataSource」,重點在sqlDataSource設定裡的「進階」必須產生Insert、Delete、Update等語法
    這個步驟我看不懂@@ 我在進階裡找不到可以讓insert的語法 還是要再進階屬性中設定什麼嗎?

    回覆刪除
  20. http://3.bp.blogspot.com/_YumVw6wEA3c/SoI1_a11kRI/AAAAAAAAAwo/F5yg381yNoI/s1600-h/VSSQL_09.png

    這是這張圖 ^_^

    回覆刪除
  21. 大大您好!關於
    If e.CommandName = "GridInsert" Then
    GridView1.DataSourceID = Nothing
    這邊是否是C# GridView1.DataSourceID=NULL;的意思呢?這樣的話那輸入資料後按新增後的參數會傳遞到哪邊呢?
    因我現在按新增會沒反應,能否給我各方向?謝謝你

    回覆刪除
  22. 想請問大家為什麼我新增的資料不會到資料庫呢.....
    是要在BACKGRIDVIEW按鈕後端再打程式碼嗎

    回覆刪除
  23. 你好,請問此方法也可以用在vs2010的網站功能上嗎?

    回覆刪除
  24. 我有幾個問題想請教一下!
    1. DetailsView裡,在某一欄位的InsertItem Template裡,加了一個ChecnBoxList,我要如何將值取到?
    因為我看了很多人,都寫在DetailsView1_ItemCreated Event中,直接用DetailsView1.XXXXX,為什麼我會沒辦法用DetailsView1物件?
    2.外層的GridView1,我也加了一個ChecnBoxList,是for Update使用,db中的值:"a,b",我要如何做?才能達到,開始update畫面時,a和b的list被selected?

    回覆刪除
  25. 感謝您這篇的分享 我是用C#來做 參考您的VB語法後有寫出來^^ 謝謝你

    回覆刪除
  26. Dear 大大
    請問如果DetailsViews裡面有日期欄位, 我該怎防呆...因為如果輸入不是日期格式會出現錯誤訊息"字串未被辨認為有效的 DateTime。"
    煩請指教..謝謝

    回覆刪除
  27. 作者已經移除這則留言。

    回覆刪除

感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。