Home About Us SQL Interview Book Contact Us RSS
Articles
Tools
Code Snippets
Links
Tips & Tricks
FAQ
Resources
Articles
Code Snippets
Links
FAQ
Resources

Saravana Kumar
Vinod Kumar


Scrollable DataGrid with Sorting

     This article is continuation to my previous article in msdn India on "Creating Scrollable DataGrid Web Server Control". In that article i have explained about how to create scrollable datagrid with fixed header.  After reading this article, one of the frequent question from reader on that article was "how to enable default sorting in this type of datagrid". So in this article, i am going to explain how to enable sorting in scrollable Datagrid with fixed header.                                                                                                

Creating Scrollable Datagrid with Fixed Header

     Before we see how to enable sorting in scrollable Datagrid. I will give an introduction to how to create a scrollabe Datagrid. To add an vertical scrollbar to Datagrid, you need to place your Datagrid within a div tag with a fixed height and Overflow property. Overflow property is to manage the content of the object when the content exceeds the height or width of the object. So when the rows exceed your specified height a scrollbar will appear. If you place your Datagrid inside div, whole table will start scroll when you move up and down, so even header also will move up and down. So to avoid this, we need to create fixed header by creating another table only with header just about your Datagrid and disable header in your Datagrid. So when you scroll your Datagrid, only Datagrid will scroll not your header. Ok fine you have created Scrollable Datagrid then what's next, you need to enable sorting on this DataGrid. For more details about creating Scrollable Datagrid, refer this article  Creating Scrollable DataGrid Web Server Control . 

Enabling Sorting in Scrollable Datagrid

     Since header is created with different table for having fixed header, major problem in enabling sorting in scrollable Datagrid is associating header table with Datagrid. Here is the aspx code for creating  Scrollable Datagrid,

<asp:table id= "HeaderTable" cellspacing= "0" border= "1"Runat="server"  Width="800"><BR>     <asp:TableRow Runat="server" class= "tableHeader">
          <asp:TableCell Runat="server" style="WIDTH:200px" ID="Tablecell1">
                Row Number
          </asp:TableCell>
          <asp:TableCell Runat="server" style="WIDTH:200px" ID="Tablecell2">
               Company Name
          </asp:TableCell>
          <asp:TableCell Runat="server" style="WIDTH:200px" ID="Tablecell3">
               Contact Name
          </asp:TableCell>
          <asp:TableCell Runat="server" style="WIDTH:200px" ID="Tablecell4">
               Address
          </asp:TableCell

     </asp:TableRow>
 </asp:table>

<div style="OVERFLOW: auto; WIDTH: 813px; HEIGHT: 152px">

<asp:datagrid id="DataGrid1" runat="server" ShowHeader= "false"DataKeyField="CustomerID"AutoGenerateColumns= "False"PagerStyle-Visible="False"  AllowSorting="True">
     <Columns>
               <asp:templatecolumn ItemStyle-Width="200px">
                   <itemtemplate>
                         <%# Container.ItemIndex+1 %>
                   </itemtemplate>
               </asp:templatecolumn>
              <asp:boundcolumn ItemStyle-Width="200px" runat="server"
                        
                   DataField="CompanyName" HeaderText="Company Name"   SortExpression="CompanyName">
               </asp:boundcolumn>
              <asp:boundcolumn ItemStyle-Width="200px" runat="server"

                    DataField="ContactName" headertext="Contact Name"   sortExpression="ContactName">
              </asp:boundcolumn>
              <asp:boundcolumn ItemStyle-Width= "200px" runat="server"             

                    DataField="Address" headertext= "Address"  SortExpression="Address">
     </Columns>
    </asp:datagrid>
</div>

If you see closely, though we hide the header of this Datagrid. We need to give sortExpression for each column and we need to enable sorting of this Datagrid.

Next step for us to associate the sorting of this Datagrid to the header table, for this what we need to do is. We need to handle the item created event of Datagrid and we need to have following code in the item created eventhandler,   

Private Sub DataGrid1_ItemCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid1.ItemCreated
        If e.Item.ItemType = ListItemType.Header Then
            Dim i As Int16
            For i = 0 To e.Item.Controls.Count - 1
                If e.Item.Controls(i).HasControls Then
                    Dim lbutton As New LinkButton
                    Dim oControl As New LinkButton
                    oControl = CType(e.Item.Controls(i).Controls(0), LinkButton)
                    lbutton.ID = oControl.ID
                    lbutton.Text = oControl.Text
                    HeaderTable.Rows(0).Controls(i).Controls.Clear()
                    HeaderTable.Rows(0).Controls(i).Controls.Add(lbutton)
                End If
            Next
        End If
    End Sub

Here what we are doing is, we are checking whether created item is header. If it is header then get the linkbutton control inside header for each column and place it in header table. Since control inside Datagrid header column in Datagridlinkbutton, we cant place this inside normal asp:table control. So we need to create linkbutton which is having same properties as this datagridlinkbutton and place it in header table.   

Private Sub DataGrid1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid1.ItemDataBound
        If e.Item.ItemType = ListItemType.Header Then
            Dim i As Int16
            For i = 0 To e.Item.Controls.Count - 1
                If e.Item.Controls(i).HasControls Then
                    Dim lbutton As New LinkButton
                    Dim oControl As New LinkButton
                    oControl = CType(e.Item.Controls(i).Controls(0), LinkButton)
                    lbutton = HeaderTable.Rows(0).Controls(i).Controls(0)
                    lbutton.Attributes.Add("href", Page.GetPostBackClientHyperlink(oControl, ""))
                End If
            Next
        End If
    End Sub

Final step is handling item databound event of Datagrid and get the postbackevent for this datagridlinkbutton and put it in linkbutton of header table. Getting the postbackevent has to be done only in item databound as data for Datagrid is created during databound only. So postbackevent will available only during item databound. Next question that arise in our mind is why cant i create linkbutton in item databound event handler itself instead overriding itemcreated event just to create controls. This is because item databound will be fired only when we bind data to the datagrid, it might not fire during postback so this dynamic controls wont be created during postback. To avoid this only we are creating this dynamic controls in item created event.

Since postbackevent of Datagrid header column is associated with header table column, when you click header table column for sorting. It will fire the sortCommand event of Datagrid, where you can write code for sorting. This is how you can enable sorting in Datagrid.