【问题标题】:ASP repeater sorting ItemDataBoundASP 中继器排序 ItemDataBound
【发布时间】:2017-06-30 14:21:18
【问题描述】:

我在使用 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 中,我们会重新计算任务到期日期。

    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

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

谢谢

【问题讨论】:

  • 我不明白这个问题。标签文本与转发器的数据源的顺序无关。为什么要按标签文本订购?你做对了,你按DateTime 排序,而不是按字符串排序。
  • 它不会解决您的问题,但您可以通过删除数据源末尾的 ToList() 调用来提高性能(节省一些内存)。
  • 感谢 cmets 伙计们。我已经删除了 ToList() 因为这从来不需要。 @TimSchmelter - 基本上我的问题是我在 page_load 上对数据源进行了排序,但我重新计算了 ItemDataBound 中的一些数据,但此时数据已经排序。我想按重新计算的数据排序
  • @GaryBurge:为什么不在分配数据源之前“重新计算”它?

标签: asp.net vb.net repeater


【解决方案1】:

您可以将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

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

【讨论】:

  • 谢谢乔尔,非常感谢您提供的信息。不幸的是,我仍在为此苦苦挣扎。我需要在 Function(r) 中插入什么逻辑?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多