ASP转发器排序ItemDataBound

时间:2017-06-30 14:21:19

标签: asp.net vb.net repeater

我在使用ASP中继器时遇到了一些麻烦并尝试对数据进行排序。

所以在Page_Load上我获得了如下的数据源......

    Protected Overloads Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
        If Not (Page.IsPostBack) Then

            'No need to re-load Occasion because it's done in the PreLoad event
            Me.Header.Title = "OCP - " + Occasion.Checklist.name

            pnlStatistics.Visible = Not (Occasion.isClosed)
            pnlClose.Visible = SecurityHelper.HasRole(SecurityMatchOption.AtLeast, SecurityRole.Manager, _relevantTeam) And Not (Occasion.isClosed)

            'initially assume checklist can be closed. any un-signed off task in the item_databound event will disable it.
            btnClose.Enabled = True

            'Fix Issue 63: rptTask.DataSource = _db.vw_tasklists.Where(Function(o) o.occasionId = Occasion.id).ToList()
            rptTask.DataSource = _db.vw_tasklists.Where(Function(o) o.occasionId = Occasion.id).OrderBy(Function(t) t.taskDueDate).ThenBy(Function(t) t.taskDueTime)

然而,在ItemDataBound中,我们重新计算任务duedate。

    Private Sub rptTask_ItemDataBound(sender As Object, e As RepeaterItemEventArgs) Handles rptTask.ItemDataBound

        ' Get the data relating to this task 'row'
        Dim t = CType(e.Item.DataItem, vw_tasklist)

        If e.Item.ItemType = ListItemType.Header Then
            Dim thDueDate = CType(e.Item.FindControl("thDueDate"), HtmlTableCell)

            thDueDate.Visible = Not (Occasion.isClosed)
        End If

        'securable buttons

        If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then

            ' Dynamically create a span element named TASKnnnn, which will be referenced from
            ' 'child page' links back to this page in order to vertically reposition at the selected task
            Dim span = New HtmlGenericControl("span")
            span.ID = "TASK" & t.taskId
            span.ClientIDMode = ClientIDMode.Static                             ' prevent ASP.NET element ID mangling
            e.Item.FindControl("lblTaskName").Parent.Controls.AddAt(0, span)    ' hook it into the repeater row

            Dim btnSignoff = CType(e.Item.FindControl("btnSignOff"), Button)
            Dim btnComment = CType(e.Item.FindControl("btnComment"), Button)
            Dim btnAmend = CType(e.Item.FindControl("btnAmend"), Button)
            Dim btnView = CType(e.Item.FindControl("btnView"), Button)
            Dim lblSoTime = CType(e.Item.FindControl("lblSOTime"), Label)
            Dim lblDueDate = CType(e.Item.FindControl("lblDueDate"), Label)
            Dim lblTaskId = CType(e.Item.FindControl("lblTaskId"), Label)
            Dim lblTaskName = CType(e.Item.FindControl("lblTaskName"), Label)

            lblTaskId.Text = CType(t.taskId, String)

            lblTaskName.Text = t.taskName

            Dim time = (If(t.taskDueTime Is Nothing, New TimeSpan(0, 23, 59, 59), TimeSpan.Parse(t.taskDueTime)))
            Dim dueDateTime As DateTime = (Occasion.started.Date + time)

            'Setup up due DateTime for Daily Tasks
            Select Case DirectCast(t.taskDayTypeId, helpers.Constants.enDayType)
                Case helpers.Constants.enDayType.Daily
                    lblDueDate.Text = dueDateTime.ToString("dd/MM/yyyy HH:mm")
                    Exit Select
                Case Else
                    'Calculate the actual due date for non-daily tasks
                    Dim calculator = New Calculator()
                    Dim calId = t.taskCalendarId
                    Dim taskMonthDay = "1"
                    If Not t.taskMonthDayId Is Nothing Then
                        taskMonthDay = CType(t.taskMonthDayId, String)
                    End If
                    Dim monthDay = _db.MonthDays.First(Function(m) m.id = CInt(taskMonthDay))
                    Dim calendar As Model.Calendar = Nothing
                    If Not calId is Nothing Then
                        calendar = _db.Calendars.First(Function(x) calId.Value = x.id)
                    End If
                    Dim potDate = calculator.GetActualDueDate(dueDateTime, monthDay.monthDay, t, calendar)
                    dueDateTime = (potDate.Date + time)
                    lblDueDate.Text = dueDateTime.ToString("dd/MM/yyyy HH:mm")
                    Exit Select
            End Select

因此,一旦数据显示在转发器中,则排序错误。我需要能够在到期日期重新计算之后对数据进行排序。这怎么可能?

由于

1 个答案:

答案 0 :(得分:0)

您可以将ItemDataBound逻辑移到原始查询中:

rptTask.DataSource = _db.vw_tasklists.
    Where(Function(o) o.occasionId = Occasion.id).
    Select(
          Function(r)
              'Fill in the logic here so the DueProperty has your real Due Date
              New With {.Row = r, .DueDate = r.TaskDueDate + r.TaskDueTime}
           End Function
    OrderBy(Function(t) t.DueDate). ' Now we only need one OrderBy (the time is already included).
    Select(Function(r) r.Row) 'But we do want to select back to the original record for the databinding
    'And the ToList() was probably NEVER needed or helpful in this situation

此外,由于这看起来像linq-to-sql,我可能会稍微分解一下,所以我们将我们期望在数据库上执行的内容与我们期望在Web服务器上执行的内容完全分开:

'This runs on the databsae
Dim sqlData = _db.vw_tasklists.
    Where(Function(o) o.occasionId = Occasion.id)

'This runs on the web server
rptTask.DataSource = sqlData.
    Select(
          Function(r)
              'Fill in the logic here so the DueProperty has your real Due Date
              New With {.Row = r, .DueDate = r.TaskDueDate + r.TaskDueTime}
           End Function
    OrderBy(Function(t) t.DueDate). ' Now we only need one OrderBy (the time is already included).
    Select(Function(r) r.Row) 'But we do want to select back to the original record for the databinding
    'And the ToList() was probably NEVER needed or helpful in this situation

当然,如果您开始将信息放入数据库中,您将获得最佳结果,这样您就可以在一开始就正确地对数据进行排序。