Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

DataGridDemo

0.00/5 (No votes)
15 Jul 2002 1  
Using the ASP.NET DataGrid for fun and profit

Introduction

The ASP.NET DataGrid control is very powerful and versatile. A dataset can be bound and displayed with almost no effort and extending the control to fit the needs of a project is very easy as we will see in this tutorial.

AutoGenerateColumns

The simplist way to use a DataGrid is to allow the .NET library to do the work. This is easily accomplished by setting the AutoGenerateColumns property to true and binding it to a datasource.

DataGrid1.DataSource = sqlCmd.ExecuteReader();
DataGrid1.DataBind();

The above code will assign the SqlDataReader returned from the SqlCommand.ExecuteReader method to the DataGrid1.DataSource. The call to DataGrid1.DataBind() will cause the control to iterate through the DataReader and create the columns and populate the rows appropriately for the contents.

Bound Columns

One drawback with the AutoGenerateColumns method is that all columns in the dataset will be displayed. If you want more control you need to use bound columns. To access the DataGrid properties dialog, either right click on the DataGrid on your form and choose Property Builder, or click on the ellipse button next to the columns collection in the property browser.

To add a bound column, select it the Available columns listbox then click the arrow button. Select the column in the Selected columns listbox, First Name in this case. When a new column is added it will be displayed as Bound Column in the listbox. Now you can set the propeties necessary to display the column in you DataGrid. If you want to display a name in the header for this column enter it in the Header text textbox. This will also change the name in the Selected columns listbox. Enter the field name from the dataset you wish to bind to this column in the Data Field textbox.

The Data formatting expression textbox is used to apply any formatting to the displayed data. For instance if the field is numeric and you want it displayed as a currency you would enter {0:c} in this field. The Visible checkbox can be used to hide columns you want populated but not visible. The ordering of the columns can be changed by moving them up or down in the Selected columns listbox.

Hyperlink Columns

Hypertext Columns are used to obviously display a hypertext link in the data column. The text of the link can be configured in the Text textbox and the URL in the URL text box. As with bound columns the Text field textbox is used to set the dataset field to bind this column to. This will only set the text of the hyperlink not the URL. The URL field is used to bind the link to a dataset field. The URL format string is used to format the hyperlink if necessary.

Template Columns

To get more creative with how the DataGrid is rendered we need to use Template Columns. Any column can be changed into a Template Column by clicking the link on the DataGrid properties page. As can be seen in this code snippet the default template uses a label control for normal display and a textbox control while in edit mode.

<asp:TemplateColumn HeaderText="First Name">
    <ItemTemplate>
        <asp:Label runat="server" 
        Text='<%# DataBinder.Eval(Container, "DataItem.au_fname") %>' />
    </ItemTemplate>
    <EditItemTemplate>
        <asp:TextBox runat="server" 
        Text='<%# DataBinder.Eval(Container, "DataItem.au_fname") %>' />
    </EditItemTemplate>
</asp:TemplateColumn>

The Text property of these controls are set by using the DataBinder.Eval method. This static method uses reflection to evaluate the first parameter at runtime. In this case, Container is a DataRow from the DataReader that is bound to the DataGrid. The second parameter, DataItem.au_fname, represents the column in the DataRow. The parameters can also be written as Container.DataItem and "au_fname", which makes it slightly more clear.

Edit Mode

To place the DataGrid in edit mode you need to set the EditItemIndex property to a valid row index and rebind the DataGrid. The DataGrid will be rendered again but this time the EditTemplate will be used for the indicated row.

DataGrid1.EditItemIndex = 1;
BindData();

Although the DataGrid.EditItemIndex can be set at anytime the most user friendly way is to create a Button Column. Expanding the Button Column item in the Available columns listbox will show three predefined button columns. For our purposes add the Edit, Update, Cancel Button Column. We will leave the default values for the properties but you can change the text displayed for each by editing the appropriate textbox. The Button type combobox is used to select how the button will be displayed, either as a hyperlink or normal button.

As can be seen here the EditCommandColumn will be added to the DataGrid. During normal rendering the column will contain an Edit linkbutton, when in edit mode the column will contain both an update and cancel linkbutton.

<asp:EditCommandColumn ButtonType="LinkButton" UpdateText="Update" 
     CancelText="Cancel" EditText="Edit"></asp:EditCommandColumn>

Because these are CommandButtons you must handle the events generated and provide any necessary processing. Events can be added from the Events view of the property browser for the DataGrid.

In the Edit event handler the Item.DataSetIndex can be used to set the DataGrid.EditItemIndex. This property contains the index within the DataGrid of the row the event was generated from.

private void OnEdit(object source, 
                    System.Web.UI.WebControls.DataGridCommandEventArgs e)
{ 
    DataGrid1.EditItemIndex = e.Item.DataSetIndex; BindData(); 
}

To cancel the edit simply set the DataGrid.EditItemIndex to -1 and rebind the DataGrid. In the Update event handler you can take whatever action is necessary to update your datasource.

More Creative Editing

The above method works fine if you want to use TextBoxes for the editing but what if you want the user to be able to enter values from a selected range. In this case a bit more creativity is needed. In the EditItemTemplate, the Textbox control can be replaced with a Dropdownlist control.

<asp:dropdownlist DataSource='<%# LoadNames() %>' 
            DataTextField="au_fname" runat="server"></asp:dropdownlist>

As can be seen here the DataSource property is set at runtime by a call to the LoadNames function.

public ICollection LoadNames()
{
    SqlConnection sqlNewConnection = new SqlConnection();
    sqlNewConnection.ConnectionString = sqlConnection1.ConnectionString;

    SqlDataAdapter da = new SqlDataAdapter("SELECT au_fname FROM authors", 
                                           sqlNewConnection);
    DataSet ds = new DataSet();
    da.Fill(ds);
    
    return ds.Tables[0].DefaultView;
}

Note that a new SqlConnection must be created to obtain the DataSet for the DropDownList. This is because databinding is still occurring on the DatGrid and the SqlConnection object is still in use at this point. The DropDownList control is bound to an ICollection derived object, in this case it is the DefaultView from the first DataSet table.

After the user has made changes and clicked the Update link, the OnUpdate method will be called. This is where it can be determined which item was selected in the dropdownlist. As can be seen in this code using the FindControl method of the DataGridCommandEventArgs.Item property will return the DropDownList. You can then obtain the SelectedItem text or value depending on needs.

private void OnUpdate(object source, 
                      System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
    // Find the drop down list

    DropDownList DropList = (DropDownList)e.Item.FindControl("dlNames");
    string strTest = DropList.SelectedItem.Text;

    // Process updated data here


    DataGrid1.EditItemIndex = -1;
    BindData();
}

Checkboxes and TextBoxes

In the case of a shopping cart type application where the user would enter a quantity or select a checkbox you need to process the DataGrid a little differently. In this example only the ItemTemplate will be used. Here a TextBox has been added for the user to enter a quantity. The OnTextChanged event must either be entered by hand, or you can create the TextBox control outside the DataGrid then copy it. 

<asp:TemplateColumn HeaderText="Qty">
    <ItemTemplate>
        <asp:TextBox id="TextBox1" runat="server" 
                     Columns="3" MaxLength="3" OnTextChanged="OnQtyChanged">
        </asp:TextBox>
    </ItemTemplate>
</asp:TemplateColumn>

The OnTextChange handler is necessary because of the order events are processed when the form is submitted. When the submit button is clicked the form is posted to the server and the DataGrid is rebound which replaces any values that had been entered into the TextBoxes. By using the OnTextChanged event you have the chance to catch the value entered and store it for later use. As can be seen here the DataGridItem is obtained from the sender parameter. The TextBox control is the second control in the first cell, the first control in the cell is a Literal Control so we skip it. In this example the Text property is converted to an int and placed in the HashTable.

Checkboxes or other controls can be used in a similar manner.

protected void OnQtyChanged( object sender, System.EventArgs e)
{
    // Get the DataGrid row from the sender

    DataGridItem Item = (DataGridItem)
               (((System.Web.UI.Control)sender).NamingContainer);
    
    // Get the TextBox control in the first cell

    TextBox txtQty = (TextBox)Item.Cells[0].Controls[1];
    
    // The au_id field is not an int but if it were...

    //int nID = (int)DataGrid1.DataKeys[Item.ItemIndex];

    // For this demo just use the ItemIndex

    int nID = Item.ItemIndex;

    // Now add to the HashTable

    hashQty.Add(nID, int.Parse(txtQty.Text));
}

Conclusion

It would take a complete book to cover all the features of the DataGrid effectively but hopefully this will give you the basics necessary to begin using it in your projects. Other areas of interest are the Template styles which can give your DataGrid a distinctive look.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here