1

我正在研究一个带有数据分页的可排序列表视图。我的列表视图和分页工作正常,但我正在努力进行排序。排序本身很好;我可以按特定列(ASC 或 DESC)进行排序,但是在动态排序方面我遇到了问题,用户可以选择一列,有时还可以反转排序方向。

我的主要问题是当前在 Form_Load 事件处理程序和 Listview_Sorting 事件处理程序中触发了排序和分页数据的生成。理想情况下,我希望在表单(重新)加载和选择新数据页面时以一种方式处理列表视图的填充,并在用户单击列标题时以另一种方式(即当(重新)排序)。不幸的是,当排序事件被触发时,Form_Load 中的代码被执行,然后 ListView_Sorting 中的代码被执行。

最初,我准备放弃只是效率低下,但现在一些 Form_Load 代码正在破坏我在 Sorting 事件处理程序中所做的事情。

所以我的问题是......我如何将这些事件的处理分成两组?当页面第一次加载以及从我尝试对数据进行排序时分页数据时,如何运行一组代码?

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
4

3 回答 3

1

正如 awe 所建议的,将页面加载中的排序代码放在一个if (!Page.IsPostBack) { // default page load sorting code here }块中就足够了。

但是,在功能级别上,您可能希望创建一个通用函数,该函数接受排序列和方向作为参数并为您进行排序。然后,您只需使用默认的排序列/方向(!Page.IsPostback 条件仍然适用)从页面加载调用此函数,并根据事件参数从 ListView_Sorting 事件调用此函数。

您可以按以下方式构建您的代码:

Handle Page_Load
{
    if (!Page.IsPostBack)
    {
        // First Time Load Only
        // Identify DEFAULT Sort + DEFAULT Paging values
        // BuildGrid(Default Sort params, Default Paging params);
    }

    // there should be no data grid code in page load on a postback
}

Handle Sorting_Event
{
    // Determine NEW sorting values
    // Fetch Existing Paging values
    // BuildGrid (NEW Sort Params, OLD Paging Params);
}

Handle Paging_Event
{
    // Determine NEW paging values
    // Fetch Existing Sorting values
    // BuildGrid (OLD Sort Params, NEW Paging Params);
}
于 2009-10-09T10:44:59.273 回答
0

CJM,为了让排序和分页为您工作,您应该执行以下操作:

  • Page_Load : 将 FileArrayList 加载到成员变量中,如果 !Page.IsPostBack,排序
  • OnPreRender : 将 FileArrayList 绑定到 ListView
  • GenerateSortedArray :只处理数组排序(不绑定)
  • 分页事件:设置分页

这将需要移动您的一些代码。现在的情况是,您添加的任何分页事件都将无法正确访问您的列表。

此外,我会将您的 Session 变量更改为 ViewState,除非您希望用户一次只打开一个页面。

于 2009-10-23T17:25:10.370 回答
0

您可以IsPostbackPage_Load. 第一次加载IsPostback是假的,在任何回发时都是真的。

如果页面生命周期的顺序有问题,您可以根据 Page_PreRender 事件中的回发结果执行操作,该事件在所有控制回发事件之后触发。

编辑:
如果您将呼叫移至GenerateSortedArray(LastColumn, SortDirection)from Page_LoadtoPage_PreRender怎么办?

Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender

    '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
    GenerateSortedArray(LastColumn, SortDirection)

    'bind array to ListView
    Me.lvwMSGs.DataBind()

End Sub
于 2009-10-09T10:06:04.863 回答