I'm working on a sortable listview with data-paging. I've got the listview and paging working fine, but I'm struggling with with the sorting. The sorting in itself is fine; I can sort by a particular column (ASC or DESC), however I'm having problems when it comes to dynamic sorting where the user can pick a column and, at times, reverse the sort direction.
My main problem is that currently the generation of sorted and paged data is triggered both in the Form_Load event handler and in the Listview_Sorting event handler. Ideally, I'd want the population of the listview to be handled in one way for form (re)loading and when selecting a new page of data, and in another way when the user clicks on the column header (ie when (re)sorting). Unfortunately, when the sorting event is fired, the code in Form_Load is executed and then later the code in ListView_Sorting is executed.
Initially it was merely an inefficiency that I was prepared to let slide, but now some of the Form_Load code is fouling what I'm doing in the Sorting event handler.
So my question is... how do I seperate the handling of these events into two groups; how can I run one set of code when the page loads for the first time and when data is paged from when I'm trying to sort the data?
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'Initilize the Sort Column and Direction
Dim LastColumn As String = If(Session("SortColumn") Is Nothing, "LastWriteTime", Session("SortColumn"))
Dim SortDirection As SqlClient.SortOrder
Dim SortDirections As Dictionary(Of String, SqlClient.SortOrder) = Session("SortDirections")
If SortDirections Is Nothing OrElse Not SortDirections.ContainsKey(LastColumn) Then
SortDirection = SqlClient.SortOrder.Descending
Else
SortDirection = SortDirections(LastColumn)
End If
Call GenerateSortedArray(LastColumn, SortDirection)
End Sub
Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
'bind array to ListView
Me.lvwMSGs.DataBind()
End Sub
Private Sub lvwMSGs_ItemCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewCommandEventArgs) Handles lvwMSGs.ItemCommand
Dim file As FileInfo = New FileInfo(e.CommandArgument.ToString) '-- if the file exists on the server
If e.CommandName = "Stream" Then
If file.Exists Then 'set appropriate headers
Response.Clear()
Response.AddHeader("Content-Disposition", "attachment; filename=" & file.Name)
Response.AddHeader("Content-Length", file.Length.ToString())
Response.ContentType = "application/octet-stream"
Response.WriteFile(file.FullName)
Response.End()
Else 'if file does not exist
Response.Write("This file does not exist.")
End If
End If
End Sub
Public Sub lvwMSGs_Sorting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewSortEventArgs) Handles lvwMSGs.Sorting
Call GenerateSortedArray(e.SortExpression, SqlClient.SortOrder.Ascending)
End Sub
Private Sub GenerateSortedArray(ByVal SortColumn As String, ByVal DefaultSortDirection As SqlClient.SortOrder)
Dim dirInfo As New DirectoryInfo(Server.MapPath(AppSettings.Item("ContentDir")))
Dim FileArrayList As New ArrayList(dirInfo.GetFiles("*.msg", SearchOption.TopDirectoryOnly))
Dim SortDirections As New Dictionary(Of String, SqlClient.SortOrder)
With FileArrayList
.TrimToSize()
SortDirections = Session("SortDirections")
If Session("SortDirections") Is Nothing OrElse SortDirections.ContainsKey(SortColumn) Then
'Create dictionary, set to default and store in Session variable
If Session("SortDirections") Is Nothing Then
SortDirections = New Dictionary(Of String, SqlClient.SortOrder)
End If
SortDirections(SortColumn) = DefaultSortDirection
Session("SortDirections") = SortDirections
'Sort data according to preferences
.Sort(New FileInfoComparer(SortDirections(SortColumn), SortColumn))
Else
'retrieve previous sort direction
SortDirections(SortColumn) = 1 - SortDirections(SortColumn)
'Sort data according to preferences
.Sort(New FileInfoComparer(SortDirections(SortColumn), SortColumn))
End If
End With
With Me.lvwMSGs
.DataSource = FileArrayList
.ItemPlaceholderID = "ItemPlaceholder"
End With
End Sub