Practical ASP.NET

Databinding Without Tables: Inserting with the GridView

The final installment in Peter's series on how to use the GridView without a DataSource explores how developers can perform inserts.

This week's column continues a series I began three columns ago, looking at how to build a page that displays multiple data items extracted from a single text property. In this article, I'll provide a way to handle inserting new data from a GridView. I've broken this column into two parts: Data issues and UI issues.

Data Issues
The GridView doesn't support inserts directly, so the mechanism I use is to add a blank row to the underlying data source and then put the resulting row into edit mode. The first step is to add a button to add the new row. For the example that I've been using in this series where I'm working with a table called Parameter in a DataSet called Parameters, I'd put this code in the button's Click event:

Dim ds As Parameters = LoadData()
ds.Parameter.AddParameterRow("", "")
With Me.GridView1            
.DataSource = ds
.EditIndex = Me.GridView1.Rows.Count
            .DataBind()
            SaveData(ds, False)
End With
This code first retrieves the DataSet from the LoadData method I described in the first column (Databinding the GridView without using a Table). The code then uses the Parameter table's customized Add method to insert a new row, passing two zero-length strings to initialize the two fields in the row.

The code then sets the GridView's EditIndex to the number of rows in the GridView in order to display the new row in its EditItemTemplate (trust me -- this works). After adding a blank row to the DataSet, I call my SaveData method to have the XML in the DataSet retained (my SaveData method is also described in last week's article, Databinding without Tables: Updates and Deletes. This time I pass False in the second parameter to the SaveData method, so that the method won't update the business object with a DataSet containing a blank row.

From this point, the code already behind the Update button (described in last week's column, Databinding without Tables: Updates and Deletes) will take care of storing the data.

User Interface Issues
This isn't a perfect solution. If the user clicks the "Add Row" button twice in a row or cancels out of the update, you'll get a blank row added to the DataSet. Preventing the user from clicking the insert button twice is easy: In the button's Click event set either of the button's Enabled or Visible properties to False. Then, in both the RowUpdating and RowCancelingEdit events, set the property back to True.

To handle the user canceling out of the update and leaving a blank row you need to delete the row that you added in the button's Click event. Unfortunately, because I've chosen to save the underlying XML, rather than the whole DataSet (an issue I discussed in the first article in this series), I can't check the row's status to see if it's a new row. I could just check to see if all of the fields in the row are empty and delete any rows that have no data. However that solution could mean that I will delete rows that the user wanted to keep but wanted to be blank.

I've chosen to implement a cheesy solution (and I’m open to better suggestions): I store the position of the row being inserted in the ViewState in the insert button's Click event:

Public Partial Class WebForm
    Inherits System.Web.UI.Page

Protected Sub InsertButton_Click(…
        Me.ViewState("InsertRowPos") = Me.GridView1.Rows.Count
I also initialize this value in my LoadData method when I don't find the XML version of my DataSet in the Session object:

Function LoadData() As DataView
        Dim strXML As String = Me.ViewState("XML")
        If strXML = "" Then
            Me.ViewState("InsertRowPos") = -1
In the RowCanceling event, I check to see if I'm working with that row and delete it if I am. Regardless, I set InsertRow back to its initial value:

ds = LoadData()
If e.RowIndex = Me.ViewState("InsertRowPos") Then
                ds.Parameter.Rows(e.RowIndex).Delete()
                ds.AcceptChanges()
	    SaveData(ds, False)
End If
Me.ViewState("InsertRowPos") = -1
And with that code, I’ve got a full implementation of all the update activities for a grid. With the code in the two earlier articles you can also display and sort data you find in memory, so this also completes the project I started two columns back. All the functionality you need in a GridView but without a table.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

  • .NET Core Ranks High Among Frameworks in New Dev Survey

    .NET Core placed high in a web-dominated ranking of development frameworks published by CodinGame, which provides a tech hiring platform.

  • Here's a One-Stop Shop for .NET 5 Improvements

    Culled from reams of Microsoft documentation, here's a high-level summary of what's new for performance, networking, diagnostics and more, along with links to the nitty-gritty details for those wanting to dig in more.

  • Azure SQL Database Ranked Among Top 3 Databases of 2020

    Microsoft touted the inclusion of Azure SQL Database among the top three databases of 2020 in a popularity ranking by DB-Engines, which collects and manages information about database management systems, updating its lists monthly.

  • Time Tracker Says VS Code Is No. 1 Editor for Devs, Some Working 15+ Hours Per Day

    WakaTime, which does time tracking for programmers, released data for 2020 showing that Visual Studio Code is by far the top editor/IDE used by its coders, some of whom are hacking away for more than 15 hours per day.

Upcoming Events