Sort not firing PostBack event using Dynamic Columns

Ask a Question related to ASP.NET Data Grid Control, Design and Development.

  1. #1

    Default Sort not firing PostBack event using Dynamic Columns

    I am having a problem with the DataGrid control and sorting, and have found it's realted to if you use dynamic columns or not. If I set the columns up on the aspx page and not in the code behind dynamically, the SortEvent will fire without requiring a double bind to the DataGrid. Below is code that will recreate the problem... If you comment out the ' If Not IsPostBack Then', and have it bind on every postback the event fires.

    I would prefer to not have to perfrom a double databind so any help on this is appreciated!!!

    Thanks
    -Tim Sarna

    ..ASPX Page
    ------------------------------------------
    <%@ Page Language="vb" AutoEventWireup="false" Codebehind="Dynamic.aspx.vb" Inherits="TestWeb.Dynamic" %>

    <HTML>
    <body>
    <form runat="server" ID="Form1">

    <h3>DataGrid Paging/Sorting - Dynamic Columns</h3>

    <asp:DataGrid id="DataGrid1" runat="server" BorderColor="black"
    AllowPaging="true" AutoGenerateColumns="false" AllowSorting="True">
    <HeaderStyle BackColor="#00aaaa"></HeaderStyle>
    <PagerStyle Mode="NextPrev"></PagerStyle>
    </asp:DataGrid>
    </form>
    </body>
    </HTML>

    'Code Behind
    '------------------------------
    Public Class Dynamic
    Inherits System.Web.UI.Page

    #Region " Web Form Designer Generated Code "

    'This call is required by the Web Form Designer.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

    End Sub
    Protected WithEvents DataGrid1 As System.Web.UI.WebControls.DataGrid

    'NOTE: The following placeholder declaration is required by the Web Form Designer.
    'Do not delete or move it.
    Private designerPlaceholderDeclaration As System.Object

    Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
    'CODEGEN: This method call is required by the Web Form Designer
    'Do not modify it using the code editor.
    InitializeComponent()
    End Sub

    #End Region

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    If Not IsPostBack Then
    ' Need to load this data only once.
    CreateGridColumns()
    DataGrid1.DataSource = CreateDataSource()
    DataGrid1.DataBind()
    End If
    End Sub 'Page_Load

    Private Sub Sort_Change(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridSortCommandEvent Args) Handles DataGrid1.SortCommand
    ' Rebind the data.
    CreateGridColumns()
    DataGrid1.DataSource = CreateDataSource(e.SortExpression)
    DataGrid1.DataBind()
    End Sub

    Sub Page_Change(ByVal sender As Object, ByVal e As DataGridPageChangedEventArgs) Handles DataGrid1.PageIndexChanged
    ' Set CurrentPageIndex to the page the user clicked.
    DataGrid1.CurrentPageIndex = e.NewPageIndex

    ' Rebind the data.
    CreateGridColumns()
    DataGrid1.DataSource = CreateDataSource()
    DataGrid1.DataBind()
    End Sub 'Grid_Change


    Public Function CreateDataSource(Optional ByVal SortColumn As String = "IntegerValue") As ICollection
    Dim dt As New DataTable
    Dim dr As DataRow

    dt.Columns.Add(New DataColumn("IntegerValue", GetType(Int32)))
    dt.Columns.Add(New DataColumn("StringValue", GetType(String)))
    dt.Columns.Add(New DataColumn("CurrencyValue", GetType(Double)))

    Dim i As Integer
    For i = 0 To 99
    dr = dt.NewRow()
    dr(0) = i
    dr(1) = "Item " + i.ToString()
    dr(2) = 1.23 * (i + 1)
    dt.Rows.Add(dr)
    Next i

    Dim dv As New DataView(dt)
    dv.Sort = SortColumn
    Return dv
    End Function 'CreateDataSource

    Public Sub CreateGridColumns()

    Me.DataGrid1.Columns.Clear()

    Dim col As New BoundColumn

    col = New BoundColumn
    Me.DataGrid1.Columns.Add(col)
    col.HeaderText = "Number"
    col.DataField = "IntegerValue"
    col.SortExpression = "IntegerValue"

    col = New BoundColumn
    Me.DataGrid1.Columns.Add(col)
    col.HeaderText = "Item"
    col.DataField = "StringValue"
    col.SortExpression = "StringValue"

    col = New BoundColumn
    Me.DataGrid1.Columns.Add(col)
    col.HeaderText = "Price"
    col.DataField = "CurrencyValue"
    col.SortExpression = "CurrencyValue"
    col.DataFormatString = "{0:c}"

    End Sub
    End Class


    --
    Tim Sarna

    tsarna Guest

  2. Similar Questions and Discussions

    1. Control not maintaing viewState and PostBack not firing event.
      I created a nWeb Custom Control that inherits from WebControls.Panel and add a CheckBoxList to this control. I can't seem to get this control to...
    2. Postback for DataGrid Columns Added in Code Behind not firing.
      I am trying to build a web custom control that displays a datagrid, so first off I have no designer where I can drag and drop a datagrid and then...
    3. Help with Dynamic Columns in Datagrid and Postback
      Hi, I'm having problems retaining my dynamic columns during postbacks. I've read that if you create dynamic columns at runtime, you have to add...
    4. Dynamic Columns, UpdateCommand not firing
      Hello Newsgroup, I have to do dynamic building of columns in a DataGrid Webcontrol. Thanks to the MSDN article "Top Questions about the DataGrid...
    5. Dynamic Control Event Not Firing Help
      In my ASP.NEt codebehind, I declare a public var for a DataGrid. Then in the TextChanged event handler for a TextBox, I create a <div> tag, stuff...
  3. #2

    Default Re: Sort not firing PostBack event using Dynamic Columns

    The problem is that you have AutoGenerateColumns = False and so the Grid
    doesn't know when it's own sort command or pageindexchanged (or any other
    event) has fired. I set the grid to "Create Columns Automatically At Run
    Time" and changed your code to not only make it work, but make it more
    efficient. The "CreateGridColumns()" routine is no longer needed. The
    following works for me:

    ************************************************** **************************

    Public Class WebForm2
    Inherits System.Web.UI.Page

    Dim dt As DataTable

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
    System.EventArgs) Handles MyBase.Load
    If Not IsPostBack Then
    DataGrid1.DataSource = CreateDataSource()
    DataGrid1.DataBind()
    Else
    'Fetch the DataTable from the cache and use it as the datasource this
    time instead of re-creating the data
    dt = CType(Cache.Item("dataTbl"), DataTable)
    DataGrid1.DataSource = dt
    End If
    End Sub

    Private Sub DataGrid1_SortCommand(ByVal source As Object, ByVal e As
    System.Web.UI.WebControls.DataGridSortCommandEvent Args) Handles
    DataGrid1.SortCommand
    ' Rebind the data.
    Dim dv As New DataView(dt)
    dv.Sort = e.SortExpression
    DataGrid1.DataSource = dv
    DataGrid1.DataBind()
    End Sub

    Private Sub DataGrid1_PageIndexChanged(ByVal source As Object, ByVal e As
    System.Web.UI.WebControls.DataGridPageChangedEvent Args) Handles
    DataGrid1.PageIndexChanged
    ' Set CurrentPageIndex to the page the user clicked.
    DataGrid1.CurrentPageIndex = e.NewPageIndex

    ' Rebind the data.
    DataGrid1.DataBind()
    End Sub

    Public Function CreateDataSource() As DataTable
    'Populate a DataTable and return it so it can be used as the datagrid's
    datasource
    dt = New DataTable
    dt.Columns.Add(New DataColumn("Number", GetType(Int32)))
    dt.Columns.Add(New DataColumn("Item", GetType(String)))
    dt.Columns.Add(New DataColumn("Price", GetType(Decimal)))

    Dim i As Integer, dr As DataRow
    For i = 0 To 99
    dr = dt.NewRow()
    dr(0) = i
    dr(1) = "Item " & i.ToString()
    dr(2) = 1.23 * (i + 1)
    dt.Rows.Add(dr)
    Next

    'Store the resulting populated DataTable in the cache so we don't
    ' have to re-create it each time the page loads
    Cache.Insert("dataTbl", dt)

    Return dt
    End Function
    End Class




    Scott M. Guest

  4. #3

    Default Re: Sort not firing PostBack event using Dynamic Columns

    Thanks for the response.

    The example I gave was just to show where the problem was, and to show that the sort command doesn’t fire when using dynamic columns (which we need to use). I am actually able to get sorting and paging to work when I store the dataset in viewstate or cache, use AutoGeneratedColumns=True, and also if I hard code the columns on the aspx page.

    The problem I have is that I can’t store the entire dataset in viewstate (because of the size) or in cache/session (because our load balanced environment doesn’t allow us to store session – long story). With this, we are forced on paging and sorting to retrieve the data each time one of these two events occurs. What’s interesting, is that paging will fire without requiring a databind in the Page_Load, but sorting requires that we re-bind to the dataset in Page_Load and then again in the SortCommand (a double hit to the database)

    I have found a work around, by storing (cloning) only the schema information of the dataset in viewstate, and then rebinding to it in the Page_Load, and then letting the sort do a full dataset reload with the new criteria in the SortCommand method. It’s not a perfect fix, but it does reduce the amount of data stored in ViewState.

    Thanks again!
    Tim Sarna


    "Scott M." wrote:
    > The problem is that you have AutoGenerateColumns = False and so the Grid
    > doesn't know when it's own sort command or pageindexchanged (or any other
    > event) has fired. I set the grid to "Create Columns Automatically At Run
    > Time" and changed your code to not only make it work, but make it more
    > efficient. The "CreateGridColumns()" routine is no longer needed. The
    > following works for me:
    >
    > ************************************************** **************************
    >
    > Public Class WebForm2
    > Inherits System.Web.UI.Page
    >
    > Dim dt As DataTable
    >
    > Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
    > System.EventArgs) Handles MyBase.Load
    > If Not IsPostBack Then
    > DataGrid1.DataSource = CreateDataSource()
    > DataGrid1.DataBind()
    > Else
    > 'Fetch the DataTable from the cache and use it as the datasource this
    > time instead of re-creating the data
    > dt = CType(Cache.Item("dataTbl"), DataTable)
    > DataGrid1.DataSource = dt
    > End If
    > End Sub
    >
    > Private Sub DataGrid1_SortCommand(ByVal source As Object, ByVal e As
    > System.Web.UI.WebControls.DataGridSortCommandEvent Args) Handles
    > DataGrid1.SortCommand
    > ' Rebind the data.
    > Dim dv As New DataView(dt)
    > dv.Sort = e.SortExpression
    > DataGrid1.DataSource = dv
    > DataGrid1.DataBind()
    > End Sub
    >
    > Private Sub DataGrid1_PageIndexChanged(ByVal source As Object, ByVal e As
    > System.Web.UI.WebControls.DataGridPageChangedEvent Args) Handles
    > DataGrid1.PageIndexChanged
    > ' Set CurrentPageIndex to the page the user clicked.
    > DataGrid1.CurrentPageIndex = e.NewPageIndex
    >
    > ' Rebind the data.
    > DataGrid1.DataBind()
    > End Sub
    >
    > Public Function CreateDataSource() As DataTable
    > 'Populate a DataTable and return it so it can be used as the datagrid's
    > datasource
    > dt = New DataTable
    > dt.Columns.Add(New DataColumn("Number", GetType(Int32)))
    > dt.Columns.Add(New DataColumn("Item", GetType(String)))
    > dt.Columns.Add(New DataColumn("Price", GetType(Decimal)))
    >
    > Dim i As Integer, dr As DataRow
    > For i = 0 To 99
    > dr = dt.NewRow()
    > dr(0) = i
    > dr(1) = "Item " & i.ToString()
    > dr(2) = 1.23 * (i + 1)
    > dt.Rows.Add(dr)
    > Next
    >
    > 'Store the resulting populated DataTable in the cache so we don't
    > ' have to re-create it each time the page loads
    > Cache.Insert("dataTbl", dt)
    >
    > Return dt
    > End Function
    > End Class
    >
    >
    >
    >
    >
    tsarna Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139