Ask a Question related to ASP.NET Data Grid Control, Design and Development.
-
tsarna #1
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
-
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... -
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... -
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... -
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... -
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... -
Scott M. #2
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
-
tsarna #3
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



Reply With Quote

