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

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

An Extensive Examination of the DataGrid Web Control: Part 7, Part 2

By Scott Mitchell and Matthew Rouse


  • Read Part 1

  • In Part 1 of this article, we looked at how to allow for a custom editing interface from a very high level. In this part we'll dig down into the specifics!

    - continued -

    Behind the Scenes of the DataGrid


    When the DataGrid's DataBind() method is called, the contents of the specified DataSource are enumerated over. For each item in the DataSource a DataGridItem instance is added. Each DataGridItem has an ItemType property which is marked as either being an Item, an AlternatingItem, or an EditItem (there are other possible ItemTypes, but for our example, let's just focus on these three). The first DataGridItem added (and every other odd one) is marked with an ItemType of Item, while the second DataGridItem added (and every other even one) is marked as an AlternateItem.

    After the DataGridItem's ItemType is set, the any additional UI features are applied. For example, the ItemStyle, if specified, is applied to DataGridItems that are marked as Item. Realize that the DataGrid is rendered using the Table class (which, unsurprisingly, renders as an HTML table). Furthermore, the DataGridItem is derived from the TableRow class, meaning that the DataGridItem object will be rendered as an HTML TABLE row.

    Recall that the DataGrid class has an EditItemIndex property that we use when editing the DataGrid. For example, in the DataGrid's OnEditCommand event handler, all we do is set the DataGrid's EditItemIndex to the index of the row whose "Edit" button was clicked and then rebind the Data. While enumerating through the DataSource, if the current row being added is equal to the EditItemIndex then the added DataGridItem is marked as being an EditItem and an alternate rendering is applied. If the column that is to be edited is a BoundColumn, then the default TextBox is rendered, with its Text property set to the value of the column in the row being edited. If a TempalteColumn is used, the EditItemTemplate (if available) is used in rendering the editing interface for that particular column.

    So, to review, when a DataGrid's DataBind() method is called, the DataSource is enumerated through and "rows" are added to the DataGrid (essentially a glorified HTML TABLE). It is important to realize that for each "row" added to the DataGrid any databinding syntax in the "row" is resolved. This is sensical - after all, in our TemplateColumn's ItemTemplate we've used databinding syntax (the <%# ... %>) in both this part and in Part 6 and Part 4. Furthermore, any controls in the "row" being added also have their DataBind() methods called.

    Returning to our example at hand (the DropDownList in our EditItemTemplate tag), this means that the "DropDownList that is currently being edited"'s DataBind() method will be called when the DataGrid's DataBind() method of the DataGrid is called. Armed with this knowledge we might reason that we could set the DropDownList's DataSource to some DataSet and have the DropDownList's DataBind() method be automatically called. The problem is, what do we set the DropDownList's DataSource property to? The answer is to use more databinding syntax!

    Specifying the DropDownList's DataSource Property


    Essentially, we want to use our familiar databinding syntax to specify the DropDownList's DataSource. Specifically, we'll use a function that returns a DataSet that is full of the contents of the tblFAQCategory table. Our databinding syntax looks like:

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

    The GetCategories() function (which we've yet to write) will simply need to return a DataSet full of the rows from the tblFAQCategory table. This function is simple enough to write, and is shown below:

    <% @Import Namespace="System.Data" %>
    <% @Import Namespace="System.Data.SqlClient" %>
    <script language="vb" runat="server">
      'Create a connection
      Dim myConnection as New SqlConnection(connString)
      Dim ddlDataSet as DataSet = New DataSet()
    
      Function GetCategories() as DataSet
        'Populate the ddlDataSet
        Const strSQLDDL as String = _
             "SELECT FAQCategoryID, Name FROM tblFAQCategory ORDER BY Name"    
        
        Dim myDataAdapter as SqlDataAdapter = New _
                              SqlDataAdapter(strSQLDDL, myConnection)    
        
        myDataAdapter.Fill(ddlDataSet, "Categories")
    
        Return ddlDataSet
      End Function
    
      ...
    
    [View a Live Demo!]

    Be sure to take note that both the connection and the DataSet ddlDataSet are defined globally to the page, meaning that any function in this ASP.NET Web page can access these objects. The reason the connection object is defined globally is because we have two functions now - GetCategories() and BindData() - that grab database information. Rather than creating, opening, and closing separate connection objects for each of the two functions, we work with just the one, globally-defined one. (Note that the connection closes itself once it goes out of scope (when the page has completed rendering).) Don't worry if the rationale behind the globally-defined DataSet isn't immediately apparent - it will become clear soon enough!

    Our GetCategories() function is fairly straightforward, we simply fill the ddlDataSet DataSet with the results from a simple SQL query that grabs the entire contents of the tblFAQCategory table, and return the filled DataSet. Take a moment to check out the live demo to see that the DropDownList is properly populated when the "Edit" button is clicked. While things may look good upon first glance, be sure to pay closer attention to the live demo.

    Notice that when you click the "Edit" button for a given row, the DropDownList's selected index is the first item from the DataSet, not the row's category name. That is, the first FAQ is of category "Strings." However, if you click the edit button for that FAQ the DropDownList's selected item is "Application Object." Fortunately, we can fix this with a bit more databinding markup and code; we'll examine the needed code and fixes in Part 3!

  • Read Part 3



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