ASP.Net(Web表单)页面生命周期问题-区分表单加载、数据分页和命令事件

ASP.Net(Web表单)页面生命周期问题-区分表单加载、数据分页和命令事件,asp.net,webforms,event-handling,page-lifecycle,Asp.net,Webforms,Event Handling,Page Lifecycle,我正在开发一个带有数据分页的可排序列表视图。我已经让listview和分页工作得很好,但我正在努力进行排序。分类本身是好的;我可以按特定列(ASC或DESC)进行排序,但在动态排序时,我遇到了问题,用户可以选择一列,有时还可以反转排序方向 我的主要问题是,当前在Form_Load事件处理程序和Listview_Sorting事件处理程序中都会触发已排序和分页数据的生成。理想情况下,我希望在表单(重新)加载和选择新的数据页时,以及在用户单击列标题时(即重新)排序时,以一种方式处理listview的

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

我的主要问题是,当前在Form_Load事件处理程序和Listview_Sorting事件处理程序中都会触发已排序和分页数据的生成。理想情况下,我希望在表单(重新)加载和选择新的数据页时,以及在用户单击列标题时(即重新)排序时,以一种方式处理listview的填充。不幸的是,当触发排序事件时,将执行形式为_Load的代码,然后执行ListView _排序中的代码

起初,我准备让它溜走只是一种低效,但现在一些Form_加载代码污染了我在排序事件处理程序中所做的工作

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

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

您可以在
Page\u Load
中检查
IsPostback
。第一次加载时,
IsPostback
为false,在任何回发上为true

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

编辑:
如果将调用从
Page\u Load
移动到
GenerateSortedArray(LastColumn,SortDirection)
Page\u 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

您可以在
Page\u Load
中检查
IsPostback
。第一次加载时,
IsPostback
为false,在任何回发上为true

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

编辑:
如果将调用从
Page\u Load
移动到
GenerateSortedArray(LastColumn,SortDirection)
Page\u 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

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

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

您可以用以下方式构造代码:

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);
}

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

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

您可以用以下方式构造代码:

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);
}
CJM, 为了使排序和分页为您工作,您应该执行以下操作:

  • Page_Load:如果需要,将FileArrayList加载到成员变量中!Page.IsPostBack,排序
  • OnPreRender:将FileArrayList绑定到ListView
  • GenerateSortedArray:只需处理数组排序(不绑定)
  • 分页事件:设置分页时间
这需要移动一些代码。现在的情况是,无论添加什么分页事件,都无法正确访问列表

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

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

  • Page_Load:如果需要,将FileArrayList加载到成员变量中!Page.IsPostBack,排序
  • OnPreRender:将FileArrayList绑定到ListView
  • GenerateSortedArray:只需处理数组排序(不绑定)
  • 分页事件:设置分页时间
这需要移动一些代码。现在的情况是,无论添加什么分页事件,都无法正确访问列表


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

听起来像是在代码隐藏文件中手动进行数据绑定。我建议您改用DataSource元素,例如ObjectDataSource。这里有一个教程:。如上所示,数据源是手动生成的FileInfo类型的ArrayList-ObjectDataSource在这种情况下合适吗?听起来像是在代码隐藏文件中手动进行数据绑定。我建议您改用DataSource元素,例如ObjectDataSource。这里有一个教程:。正如您在上面看到的,数据源是手动生成的FileInfo类型的ArrayList-ObjectDataSource在这种情况下合适吗?IsPostback没有帮助(至少它本身没有帮助),因为数据分页使用回发。正如您在上面看到的,我有一个GeneratorSorterDarray sub接受此类参数。问题是逻辑决定了哪些值被输入到sub中,我需要区分它们