When you think ASP, think...
Recent Articles
All Articles
ASP.NET Articles
ASPFAQs.com
Message Board
Related Web Technologies
User Tips!
Coding Tips
Search

Sections:
Book Reviews
Sample Chapters
Commonly Asked Message Board Questions
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Security
Stump the SQL Guru!
Web Hosts
XML
Information:
Advertise
Feedback
Author an Article
Jobs

ASP ASP.NET ASP FAQs Message Board Feedback ASP Jobs
 
Print this Page!
Published: Wednesday, August 7, 2002

An Extensive Examination of the DataGrid Web Control: Part 7

By Scott Mitchell and Matthew Rouse


The Seventh Part in a Multi-Part Series
This article is the seventh piece of a multi-part series on using the DataGrid Web control that will span several months. The ASP.NET DataGrid Web control, which displays database information in an HTML table, is highly versatile. The basics of the DataGrid were discussed in Part 1; information on specifying display properties of the DataGrid was discussed in Part 2. In Part 3 we examined how to associate custom events with the DataGrid. In Part 4 we looked at how to extend Part 3 to provide custom sorting on the results of a DataGrid. In Part 5 we examined how to use templates to further customize the DataGrid's appearance. Part 6 examined how to use the DataGrid's built-in editing capabilities. In this part we will extend Part 6 and examine how to customize the editing interface of the DataGrid!

- continued -

  • Read Part 8
  • Read Part 9
  • Read Part 10
  • Read Part 11
  • Read Part 12
  • Read Part 13
  • Read Part 14
  • Read Part 15
  • Read Part 16
  • Read Part 17
  • Read Part 18
  • ASP.NET Data Web Controls Kick Start

    ASP.NET Data Web Controls Kick Start

    ASP.NET Data Web Controls Kick Start is author Scott Mitchell's most recent book, which thoroughly examines three of the most commonly used ASP.NET Web controls: the DataGrid, DataList, and Repeater. These three Web controls can be difficult to master due to their numerous features and capabilities. With this book, you'll quickly become an expert, learning the gritty details and true capabilities of each. This 400+ page book explores the topics in this article series in much greater depth, along with examining various topics and techniques not covered here.

    Scott Mitchell is the editor and founder of 4GuysFromRolla.com, author of the An Extensive Examination of the DataGrid Web Control article series, and author of numerous other ASP and ASP.NET books.

    [Buy this Book]
    [Visit the Book's Companion Web Site]

    Introduction


    In Part 6 of the DataGrid article series we looked at how to use the DataGrid's built-in editing features. One could add inline editing to the DataGrid's contents by simply adding an EditCommandColumn along with event handlers for the OnEditCommand, OnCancelCommand, and OnUpdateCommand. By performing these steps, the DataGrid is enhanced to include an "Edit" button on each row. When clicked, the columns in that particular row that are not marked as readonly are transformed into TextBoxes populated with the column values. The user can then edit these values and click the "Update" button. (See this screenshot, as well as this one, for an idea of what this would look like.)

    These TextBoxes are the default editing interface, but you can customize this editing interface to allow for more flexibility. For example, if one of your DataGrid columns is a True/False field, you could have the DataGrid display a True/False pair of radio buttons instead of the default TextBox. Likewise, if one column was a foreign key to a lookup table, you might want to present the user with a DropDownList of applicable choices, as opposed to letting them type in a value in the TextBox. Note that to customize the DataGrid's editing interface requires a bit of extra markup in the DataGrid Web control as well as some light additional code. The code and markup, I think you'll find, is relatively simple; the difficulty, in my opinion, lies in understand what, exactly, is happening behind the scenes!

    Customizing the Editing Interface with EditItemTemplate


    In order to customize the DataGrid's editing interface you have to be using a TemplateColumn. Recall from Part 5 of the series that TemplateColumns can be added to a DataGrid to allow for additional customization of the HTML output that is rendered when the DataGrid is DataBinded to its DataSource. If you use a BoundColumn to represent a column in the DataGrid, the editing interface will be the default TextBox.

    In this article we will work through a real-world example. In the previous articles in this series, we've used live demos against the FAQ database over at ASPFAQs.com. This database is comprised of a number of tables, the main one being tblFAQ, which has a row for each FAQ. One of the columns in the tblFAQ table is called FAQCategoryID, and is a foreign key to the tblFAQCategory table, which has a row for each FAQ category (these categories include Array, Appilcation Object, Email, ASP.NET, Forms, etc.). Specifically, the important parts of these tables are defined as follows:

    tblFAQ
    FAQIDPrimary Key, integer
    Descriptionvarchar(255) - the "question" part of the FAQ
    FAQCategoryIDAn integer foreign key to the tblFAQCategory table
    Remaining rows omitted for brevity...
    tblFAQCategory
    FAQCategoryIDPrimary Key, integer
    Namevarchar(255) - the "title" of the category (Array, ASP.NET, etc.)

    Using the knowledge you have attained in the past 6 installments of this article series, you should be able to quickly and easily create a DataGrid that displayed a row for each FAQ, including the FAQ's category name (as opposed to an integer). The following SQL statement would be sufficient to tie in the appropriate category name for each FAQ:

    SELECT FAQID, F.FAQCategoryID, Name AS CategoryName, Description
    FROM tblFAQ F
      INNER JOIN tblFAQCategory FC ON FC.FAQCategoryID = F.FAQCategoryID
    [View a Live Demo!]

    In fact, I have whipped up a simple live demo to illustrate this. Nothing too fancy here, obviously. Now, imagine that you wanted to let the user edit the DataGrid. You may think, "Well, I've read Part 6 of this article series, so I know what to do! Let me just add an EditCommandColumn and go from there!" This is definitely the correct first step, but we have more to do after this due to the undesirable editing interface the BoundColumns create when in edit mode. Check out this live demo and be sure to click on Edit for a row. What do you see?

    A screenshot of the DataGrid when being edited. In case you're too lazy to try out the live demo, the screenshot to the right shows the result. Note that the Category column has been transformed into the default TextBox in editing mode. At first this may not seem like that bad of a proposal. If someone wanted to change the Category for FAQ #2 from Strings to Arrays, they could simply type in Arrays. Of course this is not optimal for a number of reasons. First, recall that the Category for each FAQ is stored as a foreign key to the tblFAQCategory table, not as a string (such as "Arrays"). While you could scan the tblFAQCategory for an appropriate category name, and then use that row's corresponding FAQCategoryID to update the edited tblFAQ row, that would be messy; furthermore, what if the user made a typo, typing in "String" instead of "Strings?" Would you display an error message? Assume they meant to enter Strings? Create a new row in tblFAQCategory?

    Clearly the ideal approach would be not to display a TextBox for the Category when the row was edited, but instead a listbox with the appropriate category values for the user to select from. To accomplish this we can customize the HTML outputted when a row is selected to be edited by specifying an EditItemIndex control in a TemplateColumn. Recall that for a DataGrid column to have a customized editing interface, the column must be a TemplateColumn, not a BoundColumn; so, the first thing we need to do is transform the BoundColumn that displays the category name into a TemplateColumn. The following simple TemplateColumn and ItemTemplate pair will do the trick (be sure to read Part 5 of this article series for more information on using TemplateColumns):

    <asp:datagrid id="dgPopularFAQs" runat="server" ... >
      <Columns>
    	<asp:EditCommandColumn EditText="Edit" CancelText="Cancel" 
    	               UpdateText="OK" />
    	  
        <asp:BoundColumn DataField="FAQID" ItemStyle-Width="10%" ReadOnly="True"
    			ItemStyle-HorizontalAlign="Center" HeaderText="FAQ ID" />
    	    
        <asp:TemplateColumn HeaderText="Category">
          <ItemTemplate>
            <%# DataBinder.Eval(Container.DataItem, "CategoryName") %>
          </ItemTemplate>
        </asp:TemplateColumn>
    
        <asp:BoundColumn DataField="Description" HeaderText="FAQ Question" />
      </Columns>
    </asp:datagrid>
    

    Here we simply display the result of the CategoryName column from the DataSource. We are not done yet; currently if the user clicks the "Edit" button there will be no special rendering for the category name column. That is, they will just see the text of the category name, no TextBox, no DropDownList, etc. This is because when we don't use a BoundColumn we need to specify the HTML to use when the row is in edit mode. We do this by using the EditItemTemplate control inside the TemplateColumn control (much like the ItemTemplate control to display the HTML to render when the row is not in edit mode).

    Since we want to show a DropDownList for the category names in edit mode, let's start by simply adding an ASP.NET DropDownList Web control to the EditItemIndex, like so:

        <asp:TemplateColumn HeaderText="Category">
          <ItemTemplate>
            <%# DataBinder.Eval(Container.DataItem, "CategoryName") %>
          </ItemTemplate>
          
          <EditItemTemplate>
            <asp:DropDownList runat="server" id="lstCategories"
                    DataValueField="FAQCategoryID"
                    DataTextField="Name"
                    DataSource="???" />
           </EditItemTemplate>                
        </asp:TemplateColumn>
    

    Since this DropDownList will contain a list of the existing FAQ categories, we will be using databinding to bind the DropDownList to a DataSource that is comprised of the contents of the tblFAQCategory table. When using a databound DropDownList, you need to specify the what column from the DataSource you wish to have displayed as the text for each DropDownList option, and what value you want tied to these textual labels. Since we want to display a DropDownList item for each row in the tblFAQCategory table, it makes sense to have the name of the category (the Name column) displayed as the textual part of the DropDownList item, and the actual FAQCategoryID as the value of the DropDownList item. (If you are utterly confused by this, I'd highly encourage you to read: Creating Databound DropDown Lists in ASP.NET.) This is the reason I set the DataValueField and DataTextFields to the given column names above.

    Of course, realize that while we've specified the columns to bind to the DropDownList, we've yet to specify where the DropDownList's DataSource is coming from. Essentially, we need to construct a DataSet with the rows from the tblFAQCategory table. Before I delve into the specifics on this, let's take a step back and examine what's happening behind the scenes when a DataGrid is edited in Part 2. (I highly encourage that you read the following section, but if you just want to "get it working" first and understand why later, then you may skip the next section; however, you may find yourself a little confused with latter parts of the article... Regardless of your choice, continue on to Part 2 to continue with the article!)

  • Read Part 2!



  • ASP.NET [1.x] [2.0] | ASPMessageboard.com | ASPFAQs.com | Advertise | Feedback | Author an Article