DetailsView and FormView Controls in ASP.NET

Using the DetailsView Control

DetailView is one of the important control, that is mainly used in master-detail scenario. You select the record from master control (as example GridView) and selected record is displayed in DetailView control.

In general GridView control displays more than one record, but the DetailsView control displays single record from database table. When you execute your web page, DetailsView control renders an HTML table.The DetailsView supports both declarative and programmatic databinding.

DetailsView control supports the edit, insert, delete and paging functionality.

Write down the connection string in web.config file. Here Database name is Employee and table name is tblEmps.

<configuration>    
   <connectionStrings>
     <add name="conString" connectionString="Data Source=(local);Initial Catalog = Employee;Integrated Security=True" />    
   </connectionStrings>
</configuration>


Example

using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Web.UI.WebControls;
using System.Web.UI;
public partial class Default : System.Web.UI.Page
{
    SqlConnection conn;
    SqlDataAdapter adapter;
    DataSet ds;
    SqlCommand cmd;
    string cs = ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            PopulateDetailView();
        }        
    }
    protected void PopulateDetailView()
    {
        try
        {
            conn = new SqlConnection(cs);
            adapter = new SqlDataAdapter("select * from tblEmps", conn);
            ds = new DataSet();
            adapter.Fill(ds);
            DetailsView1.DataSource = ds;           
            DetailsView1.DataBind();      
        }
        catch (Exception ex)
        {
           Label1.Text = "ERROR :: " + ex.Message;
        }
    }
    protected void DetailsView1_PageIndexChanging(object sender, DetailsViewPageEventArgs e)
    {
        DetailsView1.PageIndex = e.NewPageIndex;
        PopulateDetailView();
    }
    protected void DetailsView1_ModeChanging(object sender, DetailsViewModeEventArgs e)
    {        
        DetailsView1.ChangeMode(e.NewMode);
        PopulateDetailView();
    }    
}


Output:

detailsview control

Default mode of DetailView control is ReadOnly. You can change this default behavior by using ChangeMode method.

DetailsView1.ChangeMode(DetailsViewMode.Edit);

DetailsViewMode is an enaum type that supports the following options.

  • Edit
  • Insert
  • ReadOnly
In DetailView paging is not enabled by default. For achieve paging set AllowPaging property as True. If user clicks on paging link at bottom of DetailView control, then PageIndexChanging event fires.

Another important property of DetailView control is PagerSettings. This property is used to customize the look of the paging interface. For example, you can display first, previous, next, and last links instead of page numbers in DetailView.

detailview control pager settings

<PagerSettings
                Mode="NextPreviousFirstLast"
                FirstPageText="[First Record]"
                LastPageText="[Last Record]"
                NextPageText="[Next Record]"
                PreviousPageText="[Previous Record]" />


Updating Data with the DetailsView Control

User can also update the existing database records. DetailsView control has the properety AutoGenerateEditButton. In order to update a record, set the value of AutoGenerateEditButton property as true. The AutoGenerateEditButton property automatically generates the Edit link at the bottom of DetailView control.

Next provide the value of DataKeyNames property. The DataKeyNames property holds the name of the primary key column of database table. If you do not assign value in DataKeyNames property, then you will not get the primary key for performing updating or deleting the record.

When user click on "Edit" link, update and cancel link will appears in-place of edit link. When user clicks on "Edit" link, ItemUpdating event fires.

protected void DetailsView1_ItemUpdating(object sender,  DetailsViewUpdateEventArgs  e )
{
        int ID = Convert.ToInt32(DetailsView1.Rows[0].Cells[1].Text);
        TextBox txtName = DetailsView1.Rows[1].Cells[1].Controls[0] as TextBox;
        TextBox txtGender = DetailsView1.Rows[2].Cells[1].Controls[0] as TextBox;
        TextBox txtSalary = DetailsView1.Rows[3].Cells[1].Controls[0] as TextBox;
        TextBox txtAddress = DetailsView1.Rows[4].Cells[1].Controls[0] as TextBox;
        TextBox txtDepartmentID = DetailsView1.Rows[5].Cells[1].Controls[0] as TextBox;

        string updateQuery = "update tblEmps set name='" + txtName.Text + "',gender='"
        + txtGender.Text + "',Salary=" + txtSalary.Text + ",Address='" + txtAddress.Text + "',DepID="
        + txtDepartmentID.Text + " where EmpID=" + ID;
        conn = new SqlConnection(cs);
        cmd = new SqlCommand(updateQuery, conn);
        conn.Open();
        cmd.ExecuteNonQuery();
        conn.Close();
        DetailsView1.ChangeMode(DetailsViewMode.ReadOnly);
        PopulateDetailView();        
}


updating data with detailsview

When you perform edit operation, then by default you will not get any type of validation. You cannot restrict the user to enter null values or illegal value. If you need to provide validation with input data, then you should use templates with the DetailsView control.

<Fields>
     <asp:TemplateField HeaderText="Title:">
        <EditItemTemplate>
            <asp:TextBox id="txtName" Text='<%# Bind("Name") %>' runat="server" />
            <asp:RequiredFieldValidator id="reqName" ControlToValidate=" txtName "
            Text="(required)" Display="Dynamic" Runat="server" />
        </EditItemTemplate>
     </asp:TemplateField>
</Fields>


Inserting Data with the DetailsView Control

For inserting the new record into the database, first set the value of AutoGenerateInsertButton property as True. It will automatically generate the "New" link at the bottom of DetailView control.

When you click on the new link of DetailView control, the UI will be changed and blank editable text will appear. Now you have to find these textbox control that is available inside the DetailView control.

For inserting the record in database table, write the code in "ItemInserting" event as given below.

protected void DetailsView1_ItemInserting(object sender, DetailsViewInsertEventArgs e)
    {
        TextBox txtEmpID = DetailsView1.Rows[0].Cells[1].Controls[0] as TextBox;
        TextBox txtName = DetailsView1.Rows[1].Cells[1].Controls[0] as TextBox;
        TextBox txtGender = DetailsView1.Rows[2].Cells[1].Controls[0] as TextBox;
        TextBox txtSalary = DetailsView1.Rows[3].Cells[1].Controls[0] as TextBox;
        TextBox txtAddress = DetailsView1.Rows[4].Cells[1].Controls[0] as TextBox;
        TextBox txtDepartmentID = DetailsView1.Rows[5].Cells[1].Controls[0] as TextBox;
        string insertQuery = "insert into tblEmps values("+txtEmpID.Text+",'"+txtName.Text+"',
        '"+txtGender.Text+"',"+txtSalary.Text+",'"+txtAddress.Text+"',"+txtDepartmentID.Text+")";
        conn = new SqlConnection(cs);
        cmd = new SqlCommand(insertQuery, conn);
        conn.Open();
        cmd.ExecuteNonQuery();
        conn.Close();
        DetailsView1.ChangeMode(DetailsViewMode.ReadOnly);
        PopulateDetailView();
}


inserting data with detailsview

Deleting Data with the DetailsView Control

For enabling delete functionality with the DetailsView control, set the value AutoGenerateDeleteButton property as true. It will automatically generate the "Delete" link at the bottom of DetailView control.

protected void DetailsView1_ItemDeleting(object sender, DetailsViewDeleteEventArgs e)
{
        int ID = Convert.ToInt32(DetailsView1.Rows[0].Cells[1].Text);       
        string deleteQuery = "delete tblEmps where empid = "+ID;
        conn = new SqlConnection(cs);
        cmd = new SqlCommand(deleteQuery, conn);
        conn.Open();
        cmd.ExecuteNonQuery();
        conn.Close();
        DetailsView1.ChangeMode(DetailsViewMode.ReadOnly);
        PopulateDetailView();
}


Displaying Empty Data with the DetailsView Control

There may be case that there is no results are returned from its data source or no matching records are found. For handling such situation DetailsView control supports two properties that you can use to display user friendly message.

You can use the EmptyDataText property, or the EmptyDataTemplate property.
In my database table, there is no employee whose empID is 100. Therefore if we write select query like "select * from tblEmps where empID=100", then we will not get any record. In this situation we can use EmptyDataText property.

If you want to display more complicated UI or message, then you can use <EmptyDataTemplate> as given below.

<style type="text/css">
        .noRecord
        {
            background-color: #b6ff00;
            padding:15px;
            font-family: Arial;
        }
         .noRecord h1
        {
                color: red;
                font-size: 15px;
                font-weight: bold;
        }
</style>

<EmptyDataTemplate>
                <div class="noRecord">
                       <h1>No Matching Record!</h1>
                         Please select a different record.
                </div>
</EmptyDataTemplate>


displaying empty data with detailsview

Using the FormView Control

The working of FormView control is same as DetailView control but the default UI of FormView control is different. DetailView control displays the records in tabular format. FormView control does not have predefined layout but it depend upon template. According to the need of application, you can display the data with the help of template.

You can insert, update, delete and paging the record in FormView. Adding validation controls to a FormView is easier than DetailView control. For displaying data, ItemTemplate is used.

Displaying Data with the FormView

displaying data with formview

using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Web.UI.WebControls;
using System.Web.UI;

public partial class FormViewDemo : System.Web.UI.Page
{
    SqlConnection conn;
    SqlDataAdapter adapter;
    DataSet ds;
    SqlCommand cmd;
    string cs = ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            PopulateFormView();
        }
    }
    protected void PopulateFormView()
    {
        try
        {
            conn = new SqlConnection(cs);
            adapter = new SqlDataAdapter("select * from tblEmps", conn);
            ds = new DataSet();
            adapter.Fill(ds);
            FormView1.DataSource = ds;
            FormView1.DataBind();
        }
        catch (Exception ex)
        {
            Label1.Text = "ERROR :: " + ex.Message;
        }
    }
    protected void FormView1_ModeChanging(object sender, FormViewModeEventArgs e)
    {
        FormView1.ChangeMode(e.NewMode);
        PopulateFormView();
    }
}


The ItemTemplate supports a databinding expression that is used to bind the database table column. The Eval() or Bind()  method is used to retrieves the values of these columns.

<ItemTemplate>
        <table border="1">
                <tr>
                        <th><b>EmpID:</b></th>
                        <td ><%# Eval("EmpID") %></td>
                </tr>
                <tr>
                        <td><b>Name:</b></td>
                        <td ><%# Eval("Name") %></td>
                </tr>
                <tr>
                        <td><b>Gender:</b></td>
                        <td ><%#Eval("Gender") %></td>
                </tr>
                <tr>
                        <td><b>Salary:</b></td>
                        <td><%# Eval("Salary") %></td>
                </tr>
                <tr>
                        <td><b>Address:</b></td>
                        <td><%# Eval("Address") %></td>
                </tr>
                <tr>
                        <td><b>DepID:</b></td>
                        <td><%#Eval("DepID") %>
                </tr>
        </table>
         <asp:LinkButton  ID="lnkEdit"    Text="Edit"  CommandName="Edit"   runat="server" />
         <asp:LinkButton  ID="lnkNew"    Text="New" CommandName="New" runat="server" />
         <asp:LinkButton ID="lnkDelete" Text="Delete" CommandName="Delete" runat="server" />                         
</ItemTemplate>


Paging Through Data with the FormView Control

You can perform paging with FormView Control by using its AllowPaging property. By default AllowPaging property is false. Set the value of AllowPaging property as true for performing the paging. It will generate the paging link automatically. Write code in PageIndexChanging event as follows.

protected void FormView1_PageIndexChanging(object sender, FormViewPageEventArgs e)
{
        FormView1.PageIndex = e.NewPageIndex;
        PopulateFormView();
}


paging data with formview

Editing Data with the FormView Control

The FormView control uses templates to edit records. It enables you to use EditItemTemplate and specify the user interface. If you want simply display the record then use Eval() method otherwise use Bind() method. For editing the record you must have editable control, therefore we have used TextBox control within EditItemTemplate and bind the Text property of TextBox. If you click on Edit link, then Update and Cancel link will display in place of Edit Link. By default these links are not available in FormView control. You must provide these links in template fields explicitly.

FormView control has a DataKeyNames property that is used to hold the name of the
primary key from the database table. You have to specify a primary key explicitly when editing records.

This LinkButton supports a CommandName property which has the value Edit. When you click on Edit link the FormView mode is changed from ReadOnly mode to "Edit" mode. You can use Button or ImageButton control in place of LinkButton. The Bind("EmpID") method binds the Employee ID column database tableto the Text property of the TextBox control.

<EditItemTemplate>
        <table border="1">
                <tr>
                        <th><b>EmpID:</b></th>
                        <td><asp:TextBox ID="txtEmpID" Text='<%# Bind("EmpID") %>' runat="Server" /></td>
                </tr>
                 <tr>
                        <td><b>Name:</b></td>
                        <td><asp:TextBox ID="txtName" Text='<%# Bind("Name") %>' runat="Server" /></td>
                </tr>
                <tr>
                        <td><b>Gender:</b></td>
                        <td><asp:TextBox ID="txtGender" Text='<%# Bind("Gender") %>' runat="Server"/> </td>
                </tr>
                 <tr>
                        <td><b>Salary:</b></td>
                        <td><asp:TextBox ID="txtSalary" Text='<%# Bind("Salary") %>' runat="Server" /></td>
                </tr>
                <tr>
                        <td><b>Address:</b></td>
                        <td><asp:TextBox ID="txtAddress" Text='<%# Bind("Address") %>' runat="Server" /></td>
                </tr>
                <tr>
                        <td><b>DepID:</b></td>
                        <td><asp:TextBox ID="txtDeptID" Text='<%# Bind("DepID") %>' runat="Server" /></td>
                </tr>
        </table>                  
        <asp:LinkButton ID="lnkUpdate"  Text="Update" CommandName="Update" runat="server" />
        <asp:LinkButton ID="lnkCancel"  Text="Cancel" CommandName="Cancel" runat="server" />
</EditItemTemplate>


When you click on Update link ItemUpdating event fires. We have already added TextBox in EditItemTemplate. Access these textboxes with the help of FindControl method. Write code for updating the record as given below.

protected void FormView1_ItemUpdating(object sender, FormViewUpdateEventArgs e)
{
        int ID = Convert.ToInt32((FormView1.FindControl("txtEmpID") as TextBox).Text);
        string empName = (FormView1.FindControl("txtName") as TextBox).Text;
        string empGender = (FormView1.FindControl("txtGender") as TextBox).Text;
        double empSalary = Convert.ToDouble((FormView1.FindControl("txtSalary") as TextBox).Text);
        string empAddress = (FormView1.FindControl("txtAddress") as TextBox).Text;
        int depID = Convert.ToInt32((FormView1.FindControl("txtDeptID") as TextBox).Text);
        string updateQuery = "update tblEmps set name='"+empName+"',
        gender='"+empGender+"',salary="+empSalary+",address='"+empAddress+"',
        depid="+depID+" where empid="+ID;
        conn = new SqlConnection(cs);
        cmd = new SqlCommand(updateQuery, conn);
        conn.Open();
        cmd.ExecuteNonQuery();
        conn.Close();
        FormView1.ChangeMode(FormViewMode.ReadOnly);           
        PopulateFormView();
}


editing data with formview

Inserting Data with the FormView Control

You can insert new record into the database with the help of FormView Control. FormView control supports InsertItemTemplate that is used to insert new record in database. The ItemTemplate contains the "New" Link Button. When you click on "New" Link Button, control goes from ReadOnly mode to Insert mode. Insert and Cancel LinkButton is appeared in place of "New" Link Button.

<InsertItemTemplate>
        <table border="1">
                <tr>
                        <th><b>EmpID:</b></th>
                        <td><asp:TextBox ID="txtEmpID" Text='<%# Bind("EmpID") %>' runat="Server" /></td>
                </tr>
                <tr>
                        <td><b>Name:</b></td>
                        <td><asp:TextBox ID="txtName" Text='<%# Bind("Name") %>' runat="Server" /></td>
                </tr>
                <tr>
                        <td><b>Gender:</b></td>
                        <td><asp:TextBox ID="txtGender" Text='<%# Bind("Gender") %>' runat="Server" /> </td>
                </tr>
                <tr>
                        <td><b>Salary:</b></td>
                        <td><asp:TextBox ID="txtSalary" Text='<%# Bind("Salary") %>' runat="Server" /></td>
                </tr>
                <tr>
                        <td><b>Address:</b></td>
                        <td><asp:TextBox ID="txtAddress" Text='<%# Bind("Address") %>' runat="Server" /> </td>
                </tr>
                <tr>
                        <td><b>DepID:</b></td>
                        <td><asp:TextBox ID="txtDeptID" Text='<%# Bind("DepID") %>' runat="Server" /></td>
                </tr>
        </table>                  
        <asp:LinkButton ID="lnkInsert" Text="Insert" CommandName="Insert" runat="server" />
        <asp:LinkButton ID="lnkCancel"  Text="Cancel" CommandName="Cancel" runat="server" />
</InsertItemTemplate>


When you click on Insert Link Button, ItemInserting event is fires.

protected void FormView1_ItemInserting(object sender, FormViewInsertEventArgs e)
    {
        string ID = (FormView1.FindControl("txtEmpID") as TextBox).Text;
        string empName = (FormView1.FindControl("txtName") as TextBox).Text;
        string empGender = (FormView1.FindControl("txtGender") as TextBox).Text;
        double empSalary = Convert.ToDouble((FormView1.FindControl("txtSalary") as TextBox).Text);
        string empAddress = (FormView1.FindControl("txtAddress") as TextBox).Text;
        string depID = (FormView1.FindControl("txtDeptID") as TextBox).Text;
        string insertQuery = "insert into tblEmps values("+ID+",'"+empName+"','"+empGender+"',
        "+empSalary+",'"+empAddress+"',"+depID+")";
        conn = new SqlConnection(cs);
        cmd = new SqlCommand(insertQuery, conn);
        conn.Open();
        cmd.ExecuteNonQuery();
        conn.Close();
        FormView1.ChangeMode(FormViewMode.ReadOnly);           
        PopulateFormView();
}


Output:

inserting data with formview