我一直在尝试使用Infragistics xamDataGrid(Infragistics3.Wpf.DataPresenter.v9.1.Express)实现一些自定义分组,并且几乎完全依赖Infragistics site的代码。我有两个不同的日期字段 - 截止日期和提醒日期 - 使用GroupByEvaluator。在我尝试将两个字段添加到GroupByArea之前,一切似乎都很好。
这是怎么回事:嵌套字段组根据父字段的日期而不是父字段的分组。例如,当我拖动"截止日期" (父)字段到GroupBy,它按截止日期将这些记录分为四类 - 截止到期年份,到期年份,到期日期和未设置。完善。但是,当我拖动提醒日期"字段(嵌套)到GroupBy,我会找到相同的多个标签"提醒日期"分组嵌套在截止日期"过期"。
我是SO的新手发帖,因此我无法发布图片。相反,我会输入一个:
过期(截止日期)
对于每个后续嵌套分组,最早的截止日期(父分组的值)等于或大于先前分组的最大截止日期。好像"过去"集合按截止日期asc排序,并且只要嵌套标签发生更改,它就会遍历每条记录并创建一个新的嵌套组。所以在5个GroupByRecords之后给出了#34;本月"的标签,当下一个" Not Set" groupByRecord弹出一个新的嵌套标签,而不是继续填充现有标签。
我遇到了与排序相关的问题,我怀疑这是整个问题的关键所在。如果网格已根据截止日期进行排序,则其他字段的所有按功能排序都会受到截止日期的约束。例如,按客户端名称排序不会将所有客户端名称记录排序为升序或降序。相反,它会排序,但它首先按截止日期排序,然后按名称排序。
抱歉,我无法附加图片。希望我能解释这个问题。
提前致谢!代码如下:
Imports System.Collections.ObjectModel
Imports Infragistics.Windows.DataPresenter
Imports System.Windows
Imports System.Windows.Controls
Partial Public Class ManageEntities
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Me.InitializeGroupByGrid()
End Sub
#Region "CustomGrouping"
'http://help.infragistics.com/Help/Doc/WPF/2012.2/CLR4.0/html/InfragisticsWPF4.DataPresenter.v12.2~Infragistics.Windows.DataPresenter.IGroupByEvaluator.html
Private Sub InitializeGroupByGrid()
For Each f In Me.SelectorGrid.FieldLayouts(0).Fields
If f.Name = "Form1DueDate" OrElse f.Name = "Form1LastReminderDate" Then
f.Settings.GroupByEvaluator = New CustomDateTimeEvaluator
' group by the data field
Dim fsd As FieldSortDescription = New FieldSortDescription()
fsd.Field = f
fsd.Direction = System.ComponentModel.ListSortDirection.Descending
Me.SelectorGrid.FieldLayouts(0).SortedFields.Add(fsd)
End If
Next
End Sub
#End Region
End Class
#Region "CustomDateTimeEvaluator"
'//20150918 - From infragistics: http://help.infragistics.com/Help/Doc/WPF/2013.1/CLR4.0/html/InfragisticsWPF4.DataPresenter.v13.1~Infragistics.Windows.DataPresenter.IGroupByEvaluator.html
Friend Class CustomDateTimeEvaluator
Implements IGroupByEvaluator
Private Const NotSet As String = "Not Set"
Private Const PastDue As String = "Past Due"
Private Const DueThisYear As String = "Due This Year"
Private Const DueNextYear As String = "Due Next Year"
Private Const RemindThisMonth As String = "This Month"
Private Const RemindLastMonth As String = "Last Month"
Private Const Older As String = "Older"
Dim targetDate As DateTime = Nothing
Public Function DoesGroupContainRecord(ByVal groupByRecord As GroupByRecord, ByVal record As DataRecord) As Boolean Implements IGroupByEvaluator.DoesGroupContainRecord
Dim cellValue As Object = record.GetCellValue(groupByRecord.GroupByField)
Dim desc As String = groupByRecord.Description
' handle null values specially
If cellValue Is Nothing Or TypeOf cellValue Is DBNull Then
Return desc = NotSet
End If
' if the value is not a date time, just group them together
If TypeOf cellValue Is DateTime = False Then
Return True
End If
Return desc = GetDateLabel(CType(cellValue, DateTime), groupByRecord.GroupByField.Name)
End Function
Public Function GetGroupByValue(ByVal groupByRecord As GroupByRecord, ByVal record As DataRecord) As Object Implements IGroupByEvaluator.GetGroupByValue
Dim cellValue As Object = record.GetCellValue(groupByRecord.GroupByField)
Dim desc As String = String.Empty
Dim targetDate As DateTime = DateTime.MinValue
If cellValue Is Nothing Or TypeOf cellValue Is DBNull Then
desc = NotSet
ElseIf TypeOf cellValue Is DateTime Then
targetDate = CType(cellValue, DateTime)
desc = GetDateLabel(targetDate, groupByRecord.GroupByField.Name)
End If
groupByRecord.Description = desc
Return targetDate
End Function
Public ReadOnly Property SortComparer() As System.Collections.IComparer Implements IGroupByEvaluator.SortComparer
Get
Return Nothing
End Get
End Property
Private Function GetDateLabel(ByVal dt As DateTime, ByVal fldName As String) As String
Dim d As String = NotSet
Dim comparison As Integer = Nothing
Dim currentYear As Integer = DatePart(DateInterval.Year, Now)
'//If no date, return NotSet
If dt.Ticks = 0 Then
Return d
End If
'//Group by fieldname name
If fldName.ToLower = "form1duedate" Then
'//Past Due includes any records where the Form 1 Due Date is less than July 1st of the current year
Dim cDDate As New DateTime(currentYear, 7, 1)
comparison = dt.Date.CompareTo(cDDate.Date)
If comparison = 0 Then
d = DueThisYear
ElseIf comparison < 0 Then
d = PastDue
ElseIf comparison > 0 Then
d = DueNextYear
Else
d = NotSet
End If
ElseIf fldName.ToLower = "form1lastreminderdate" Then
Dim currentMonth As Integer = DatePart(DateInterval.Month, Now)
Dim olderThanDate As New DateTime(currentYear, currentMonth - 1, 1)
If dt.Date.Year = currentYear AndAlso dt.Date.Month = currentMonth Then
d = RemindThisMonth
ElseIf dt.Date.Year = currentYear AndAlso dt.Date.Month = currentMonth - 1 Then
d = RemindLastMonth
ElseIf dt.Date < olderThanDate Then
d = Older
Else
d = NotSet
End If
End If
Return d
End Function
End Class
#End Region