Grid View and Details View in ASP.NET 2.0...

Some of the new web controls featured in the .NET framework 2.0 beta include the GridView and DetailsView objects. These controls offer more features than the 1.1 version.


By: Brian Mains Date: August 8, 2004 Download the code.

Some of the new web controls featured in the .NET framework 2.0 beta include the GridView and DetailsView object. These controls offer more features than in the 1.1 version of the framework, featuring:

These two controls, when utilized together, perform all data access operations on a data source. No coding is required to perform these actions; however, some coding may be involved to improve the UI navigability.

The GridView control has many new features that improve over the data grid control. The DataGrid control is still supported, and is completely backwards-compatible; however, the GridView controls offers many features above and beyond this control. New properties allow for the Edit, Update, Cancel, and Select command buttons to be automatically placed in the GridView, as well as complete control over its functionality.

The GridView lacks the capabilities to insert into a database, which is where the DetailsView control takes over. This control has capabilities to insert and update a row of data in a database. It also has a lot of the same properties as the GridView, yet because it deals with one row of data at a time, is a little more one-dimensional, especially with its paging capabilities.

Binding two these controls couldn't be easier with the new DataSource controls. These controls are similar to ADODB component in VB and the typed Connection and DataAdapter controls in .NET 1.1. This control expands upon these controls greatly by supporting connection string stored in the config file, data source altering based on the value of a control or other collection, and other features.

For the queries, the DataSource control defines an <asp:Parameter> control that represents a parameter for a parameterized query (defined as @<name> in the query) or stored procedure. Parameters allow for the information entered or modified by the user to be passed to the data source. In addition, the <asp:ControlParameter> control alters a result set by allowing for a control to provide a value for the where clause. Let's look at this more specifically. Whenever a row of data is selected in the GridView, the key value is accessible in the SelectedValue property. By defining the control parameter to use this SelectedValue property, the ControlParameter takes the key value (say an ID of 1 for example) and passes it as part of the where clause (which would now read something like: "select * from Table where ID = 1"). The result set is limited in this manner.

There are many versions of the DataSource control, titled: SQLDataSource, AccessDataSource, ObjectDataSource, SiteMapDataSource, and a few others. This article will use the SQLDataSource to connect to a SQL Server 2005 Express database containing some test data. To get both the GridView and the DetailsView, two SQLDataSource controls retrieve the data. The first data source retrieves all of the records in the table, which is bound to the GridView. Because the DetailsView deals with one row of data at a time, a second SQLDataSource control will limit the result set based on the SelectedValue property of the GridView. When an item is selected, the key of the table selected in the GridView is returned via this property, which is then accessible for the DetailsView. This will be illustrated later.

The first SQLDataSource control shown below features many of the changes available in the 2.0 beta. The first property, ConnectionString, allows for a hard-coded connection string, as well as linking to the web.config file via the following syntax: <%$ConnectionStrings:ExampleCS%>. The configuration file has a new section called <ConnectionStrings>, which houses all of the connection strings for an application. In addition, the data source specifies the parameterized queries or procedures through the SelectCommand, InsertCommand, UpdateCommand, or DeleteCommand property. The parameters specified in the query or procedure are then defined in the appropriate Parameters grouping (DeleteParameters, UpdateParameters, InsertParameters, or SelectParameters). These elements are children of the <asp:SQLDataSource> element, which its children define the parameter names and types defined in the query. The code for this control appears as:

<asp:SqlDataSource ID="SqlDataSource1" Runat="server" ConflictDetection="CompareAllValues"
  ConnectionString="<%$ ConnectionStrings:ExampleCS %>" UpdateCommand="UPDATE [tblData] SET [Name] = @Name, [Description] = @Description WHERE [ID] = @original_ID AND [Name] = @original_Name AND [Description] = @original_Description"
  SelectCommand="SELECT [ID], [Name], [Description] FROM [tblData]" InsertCommand="INSERT INTO [tblData] ([Name], [Description]) VALUES (@Name, @Description)"
  DeleteCommand="DELETE FROM [tblData] WHERE [ID] = @original_ID AND [Name] = @original_Name AND [Description] = @original_Description">
  <DeleteParameters>
    <asp:Parameter Type="Int32" Name="ID"></asp:Parameter>
    <asp:Parameter Type="String" Name="Name"></asp:Parameter>
    <asp:Parameter Type="String" Name="Description"></asp:Parameter>
  </DeleteParameters>
  <UpdateParameters>
    <asp:Parameter Type="String" Name="Name"></asp:Parameter>
    <asp:Parameter Type="String" Name="Description"></asp:Parameter>
    <asp:Parameter Type="Int32" Name="ID"></asp:Parameter>
  </UpdateParameters>
  <InsertParameters>
    <asp:Parameter Type="String" Name="Name"></asp:Parameter>
    <asp:Parameter Type="String" Name="Description"></asp:Parameter>
  </InsertParameters>
</asp:SqlDataSource>

The second data source is mostly the same as the second, except with the SelectCommand. The select statement only needs to return one row of data, and so a ControlParameter is used. As stated before, the control parameter limits the result set through the use of the where clause. The control parameter defines that the where clause (where ID = @ID) should be retrieve from the GridView1.SelectedValue property. The SelectedValue property contains the primary key for the table, as defined through the DataKeyNames property in the GridView. The DataKeyNames property contains one or more of the names of the primary key(s) for the data source.

<asp:SqlDataSource ID="SqlDataSource2" Runat="server" ConnectionString="<%$ ConnectionStrings:ExampleCS %>"
  SelectCommand="SELECT [ID], [Name], [Description] FROM [tblData] WHERE ([ID] = @ID)" ConflictDetection="CompareAllValues" UpdateCommand="UPDATE [tblData] SET [Name] = @Name, [Description] = @Description WHERE [ID] = @original_ID AND [Name] = @original_Name AND [Description] = @original_Description" InsertCommand="INSERT INTO [tblData] ([Name], [Description]) VALUES (@Name, @Description)" DeleteCommand="DELETE FROM [tblData] WHERE [ID] = @original_ID AND [Name] = @original_Name AND [Description] = @original_Description">
  <DeleteParameters>
    <asp:Parameter Type="Int32" Name="ID"></asp:Parameter>
    <asp:Parameter Type="String" Name="Name"></asp:Parameter>
    <asp:Parameter Type="String" Name="Description"></asp:Parameter>
  </DeleteParameters>
  <UpdateParameters>
    <asp:Parameter Type="String" Name="Name"></asp:Parameter>
    <asp:Parameter Type="String" Name="Description"></asp:Parameter>
    <asp:Parameter Type="Int32" Name="ID"></asp:Parameter>
  </UpdateParameters>
  <SelectParameters>
    <asp:ControlParameter Name="ID" Type="Int32" ControlID="GridView1" PropertyName="SelectedValue"></asp:ControlParameter>
  </SelectParameters>
  <InsertParameters>
    <asp:Parameter Type="String" Name="Name"></asp:Parameter>
    <asp:Parameter Type="String" Name="Description"></asp:Parameter>
  </InsertParameters>
</asp:SqlDataSource>

The View objects use the first SQLDataSource by establishing the name of the data source through the DataSourceID property. The command buttons to perform operations against the data source are automatically generated via the AutoGenerateSelectButton, AutoGenerateDeleteButton, AutoGenerateEditButton, and AutoGenerateInsertButton. These buttons render in the view without having to write any code. When editing a record, the view automatically hides all other button not needed in the operation (such as the insert or delete button when editing).

The view objects also support more column types than its predecessor. They are the CheckBoxField and the ImageField columns, which display a checkbox and image in the column, instead of using a TemplateColumn. In addition, if the automatic command buttons are not desired, they can still be added to the class through the CommandField column type. One of the newest feature of using these field columns is the control over what value to display in the column when the database contains a null.

The GridView also supports new column types not supported in the DataGrid. The CheckBoxField and the ImageField support automatic displaying of checkboxes and images directly in the GridView, instead of using the TemplateColumn. In addition, the CommandField supports the display of the command buttons (Edit, Delete, Select) if Auto-generation is not an option. In addition, these fields support displaying a default value when a null value is detected in the database, something that wasn�t an option previously.

In addition, each view object supports a number of templates to change the style of the object, as well as an EmptyDataTemplate that shows when no data is returned from the database. The following code is an illustration of the GridView and DetailsView objects:

<asp:GridView ID="GridView1" Runat="server" AutoGenerateColumns="False" DataKeyNames="ID"
  DataSourceID="SqlDataSource1" CellPadding="3" BorderStyle="None" BorderColor="#CCCCCC"
  BorderWidth="1px" BackColor="White" AutoGenerateSelectButton="True" AutoGenerateDeleteButton="True" AllowSorting="True" AllowPaging="True">
  <FooterStyle ForeColor="#000066" BackColor="White"></FooterStyle>
  <PagerStyle ForeColor="#000066" HorizontalAlign="Left" BackColor="White"></PagerStyle>
  <HeaderStyle ForeColor="White" Font-Bold="True" BackColor="#006699"></HeaderStyle>
  <EmptyDataTemplate>
    No records could be retrieved from the database.  We apologize for the invonvenience.
  </EmptyDataTemplate>
  <Columns>
    <asp:BoundField ReadOnly="True" HeaderText="ID" InsertVisible="False" DataField="ID"
    SortExpression="ID"></asp:BoundField>
    <asp:BoundField HeaderText="Name" DataField="Name" SortExpression="Name"></asp:BoundField>
    <asp:BoundField HeaderText="Description" DataField="Description" SortExpression="Description"></asp:BoundField>
  </Columns>
  <SelectedRowStyle ForeColor="White" Font-Bold="True" BackColor="#669999"></SelectedRowStyle>
  <RowStyle ForeColor="#000066"></RowStyle>
</asp:GridView>

<asp:DetailsView ID="DetailsView1" Runat="server" DataKeyNames="ID" DataSourceID="SqlDataSource2"
  CellPadding="3" BorderStyle="None" BorderColor="#CCCCCC" BorderWidth="1px" BackColor="White"
  AutoGenerateInsertButton="True" AutoGenerateEditButton="True" AutoGenerateRows="False" OnItemInserted="DetailsView1_ItemInserted">
  <FooterStyle ForeColor="#000066" BackColor="White"></FooterStyle>
  <RowStyle ForeColor="#000066"></RowStyle>
  <PagerStyle ForeColor="#000066" HorizontalAlign="Left" BackColor="White"></PagerStyle>
  <Fields>
    <asp:BoundField ReadOnly="True" HeaderText="ID" InsertVisible="False" DataField="ID"
    SortExpression="ID"></asp:BoundField>
    <asp:BoundField HeaderText="Name" DataField="Name" SortExpression="Name"></asp:BoundField>
    <asp:BoundField HeaderText="Description" DataField="Description" SortExpression="Description"></asp:BoundField>
  </Fields>
  <HeaderStyle ForeColor="White" Font-Bold="True" BackColor="#006699"></HeaderStyle>
  <EditRowStyle ForeColor="White" Font-Bold="True" BackColor="#669999"></EditRowStyle>
</asp:DetailsView>

About the code

The code uses a SQL Server 2005 Express database to retrieve the data. Using two SQLDataSource controls, these provide the data to the GridView and DetailsView. When an entry is selected in the GridView, the DetailsView shows that record. Then the user can add or edit the record using the DetailsView object. Upon adding or editing the record, the following code is used to hide the details view and refresh the GridView:

Sub DetailsView1_ItemInserted(ByVal sender As Object, ByVal e As DetailsViewInsertedEventArgs) Handles DetailsView1.ItemInserted
  With GridView1
    .DataBind()
    .SelectedIndex = -1
  End With
End Sub

Sub DetailsView1_ItemUpdated(ByVal sender As Object, ByVal e As DetailsViewUpdatedEventArgs) Handles DetailsView1.ItemUpdated
  With GridView1
    .DataBind()
    .SelectedIndex = -1
  End With
End Sub

That is all of the code that is needed to then hide the data grid and refresh the result set for the GridView. The GridView contains the newly inserted or edited data. In addition, using the <EmptyDataTemplate>, if all of the rows of data are deleted, this template will appear notifying the user that there isn't any data available.

This article deviates from the common project that I was working on with the Master Pages article. I apologize for that, as these articles were originally devised at the same time.

You may download the code here.