Skip Navigation LinksHome : CBC Classes : ASP.Net : Database 3 Gridview Tied to Detailsview

CS218 ASP.Net Tying a DetailsView to a GridView (VB)


As you've seen the gridview is good for displaying multiple records, but because it's displaying multiple records there isn't much space for each individual record. This means the gridview is not very good for editing records, especially anything with much text in it, because the textboxes will have limited space. The detailsview is good for editing records, because it only displays one record at a time. However, it's painful to use the detailsview to navigate and find records.

In this section you will learn how to build a better user interface by using a gridview to display and select a record to edit. Once the record is selected, you will load that record into the detailsview for editing.

This page contains the VB version of the code. If you want the C# version check this page.


  1. Overview (video 7a1)
  2. Selecting a record in a GridView and Displaying it in a DetailsView (video 7b1)
  3. Refreshing the GridView after editing in the DetailsView (video 7b2, code)
  4. Fixing the DetailsView update same record twice problem (video, code)
  5. Hiding and showing the GridView and DetailsView (video 7c1, code)
  6. Hiding and showing the GridView and DetailsView using panels (video 7c2, code)
  7. Adding JavaScript verify code to delete buttons (video 7d1, code)
  8. Adding JavaScript verify code to cancel buttons (video 7e1, code)
  9. Trapping Database errors (video, code)

VB Code for refreshing the GridView after editing in DetailsView

This code causes the GridView to refresh it's data after making any changes from the DetailsView. If your GridView is named GridView1 and your DetailsView is named DetailsView1 you can copy and paste this code without making any changes. If you changed your control names, then change the code to match.

    Protected Sub DetailsView1_ItemUpdated(sender As Object, e As System.Web.UI.WebControls.DetailsViewUpdatedEventArgs) Handles DetailsView1.ItemUpdated
        GridView1.DataBind()
    End Sub


VB Code for fixing DetailsView update same record twice problem

There's a tricky problem that comes up if you choose to edit the same record twice in a row. In this case, the second edit seems like it doesn't get written to the database. That is, the first edits are always written to the database, but if you return to the same record without editing any other records inbetween, then the second update never makes it to the database.

It took me awhile and a lot of testing to figure out what was really going on. The root cause of the problem is that when the update from the detailview is sent to the database we refresh the data in the gridview by running the databind(). But if we return to the same record in the detailsview, the data in the detailsview never gets refreshed. It's still using the old, stale data. The solution is to add a databind to the detailsview as well as the gridview. I've added it to the gridview SelectedIndexChanged event. There are probably other event handlers you could add it to as well ...

You've probably already added most of this code. If so, just add the line of bold code.

     Protected Sub GridView1_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles GridView1.SelectedIndexChanged
        DetailsView1.DataBind()
        GridView1.Visible = False
        DetailsView1.Visible = True
    End Sub

VB Code for hiding and showing GridView and DetailsView

This code hides and shows the GridView and DetailsView so that only one is shown on the web page at any time. If your GridView is named GridView1 and your DetailsView is named DetailsView1 you can copy and paste this code without making any changes. If you changed your control names, then change the code to match.

    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            DetailsView1.Visible = False
        End If
    End Sub

    Protected Sub DetailsView1_ItemUpdated(sender As Object, e As System.Web.UI.WebControls.DetailsViewUpdatedEventArgs) Handles DetailsView1.ItemUpdated
        GridView1.DataBind()
        GridView1.Visible = True
        DetailsView1.Visible = False
    End Sub

    Protected Sub DetailsView1_ModeChanged(sender As Object, e As System.EventArgs) Handles DetailsView1.ModeChanged
        GridView1.Visible = True
        DetailsView1.Visible = False
    End Sub

    Protected Sub GridView1_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles GridView1.SelectedIndexChanged
        GridView1.Visible = False
        DetailsView1.Visible = True
    End Sub


VB Code for hiding and showing panels

This is the same code as in the previous section with a slight difference. Instead of hiding and showing a single control, this code hides and shows panels (boxes). Use this if you have any items in addition to the GridView or DetailsView that you want to hide and show. Just make sure your panel names match the names used in the code, or change the code to match your panel names. Also, do NOT change the name GridView1 in the databind statement, and do NOT change the names of the objects in the SubRoutine declarations. Only change the object names in the statements where the Visible property is being set.

    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            panelDetailsView.Visible = False
        End If
    End Sub

    Protected Sub DetailsView1_ItemUpdated(sender As Object, e As System.Web.UI.WebControls.DetailsViewUpdatedEventArgs) Handles DetailsView1.ItemUpdated
        GridView1.DataBind()  'Do NOT change this to a panel
        panelGridView.Visible = True
        panelDetailsView.Visible = False
    End Sub

    Protected Sub DetailsView1_ModeChanged(sender As Object, e As System.EventArgs) Handles DetailsView1.ModeChanged
        panelGridView.Visible = True
        panelDetailsView.Visible = False
    End Sub

    Protected Sub GridView1_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles GridView1.SelectedIndexChanged
        panelGridView.Visible = False
        panelDetailsView.Visible = True
    End Sub


JavaScript code for adding Confirm to delete button

This code adds some JavaScript to the delete button. Remember that you have to change the button fields to a template so you can add the customization. The code is added using a span element, so make sure and add the start and end tags just before and after the button. You should change the text message to be appropriate for your situation.

       <span onclick="return confirm('Are you sure you want to Delete the record?')">
           <asp:Button ID="Button2" runat="server" 
                       CausesValidation="False" 
                       CommandName="Delete" 
                       Text="Delete" />
       </span>

JavaScript code for adding Confirm to cancel button

This code adds some JavaScript to the Cancel button which is displayed when the user is editing in the DetailsView. Remember that you have to change the button fields to a template so you can add the customization. The code is added using a span element, so make sure and add the start and end tags just before and after the button. You should change the text message to be appropriate for your situation.

      <span onclick="return confirm('Your changes have not been saved. Are you sure you want to cancel? Click OK to leave the editor or CANCEL to return to the editor.')">
        <asp:Button ID="Button2" runat="server" CausesValidation="False" 
             CommandName="Cancel" Text="Cancel" />
      </span>

Code for handling DB write errors

I hope it goes without saying that you should test your code before giving to a customer, and you should correct any errors that may arise. But with databases sometimes there will be transient errors caused by the database server. That is, your code may test fine and run fone for months, but start showing errors if the database server is having problems. This code will trap database errors and allow you to present your own error message to the user instead of having them see a yellow screen.

First, create a panel that contains your custom message to the user. Here's an example of one that I use. I also included some asp:Button controls that allow the user to decide what to do next. The other crucial control is the asp:Label, which is used to display the actual error message. While you can give your asp:Label any ID, it will have to match the ID used in the code.

  <asp:Panel ID="PanelDeleteFail" runat="server" Visible="False">
  <p>
  The following error occurred while trying to delete the newsletter entry from the database:
  <asp:Label ID="lblDeleteError" runat="server" Text="Label"></asp:Label>
  </p>
    
  <asp:Button ID="cmdAdmin" runat="server" Text="Return To Admin Page" />
  <asp:Button ID="cmdRetry" runat="server" Text="Return To Edit Newsletter Page" />

  </asp:Panel>

Add the following code. If your GridView has an id of GridView1 then all you have to do is make sure the name of your panel matches the PanelDeleteFail, or change your panel's ID and the code so that the id name is the same in both places. Also make lblDeleteError match the ID of your asp:Label.

    Protected Sub GridView1_RowDeleted(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeletedEventArgs) Handles GridView1.RowDeleted
        If e.Exception IsNot Nothing Then
            PanelDeleteFail.Visible = True
            PanelGridview.Visible = False
            lblDeleteError.Text = e.Exception.Message.ToString
            e.ExceptionHandled = True
        Else
            PanelGridview.Visible = True
        End If
    End Sub

You can use code just like this to check for write and update errors as well.