login  Naam:   Wachtwoord: 
Registreer je!
 Forum

Sorteren Datagridview op binded List(Of T) (Opgelost)

Offline Ontani - 04/02/2011 16:43
Avatar van OntaniGouden medailleGouden medailleGouden medailleGouden medaille

-1
Ik heb een datagridview met z'n datasource als List(Of T). Ik zou de kolommen willen sorteren en mogelijk op elke mogelijke property van BlogPost.

  1. 'Database access : items = List(BlogPost)
  2. dgBlogPosts.DataSource = items
  3.  
  4. 'My BlogPost Class
  5. Public Class BlogPost
  6.  
  7. Public Property ID As Integer
  8. Public Property Title As String
  9. Public Property Content As String
  10. Public Property CreationDate As DateTime
  11. Public Property Rating As Decimal = 5.0
  12.  
  13. End Class

4 antwoorden

Gesponsorde links
Offline Abbas - 04/02/2011 17:24
Avatar van Abbas Gouden medaille

Crew .NET
Kan je niet met een lambda-expressie de list sorteren op een property van die list? Bijvoorbeeld:

  1. items = items.OrderBy(item => item.Title);

En dan terug toewijzen aan de DataGridView.
Offline Ontani - 04/02/2011 22:44
Avatar van Ontani Gouden medailleGouden medailleGouden medailleGouden medaille

-1
Net geprobeerd, het is doenbaar op die manier, maar dat wilt zeggen da ik voor elke datagrid waarin ik die objecten wil sorteren functies moet gaan schrijven voor de columHeaders klikbaar te maken. Aan de hand van de columnIndex ga kijken op welke property van m'n class ik moet gaan sorteren en aan de hand van de propertyType dan ook nog eens naar het juiste type moet gaan casten want OrderBy verwacht een Type parameter: OrderBy(Of Decimal) als het om een Decimal property gaat.
En gaat natuurlijk niet werken als ik op een String Column klik.
Offline Abbas - 04/02/2011 23:09
Avatar van Abbas Gouden medaille

Crew .NET
Toen ik m'n reactie las, zag ik ook meteen dit probleem. Maar ik dek dat er een manier moet zijn om dit te kunnen doen. Ik ga me der seffes is achter zetten! 
Offline Ontani - 07/02/2011 12:01
Avatar van Ontani Gouden medailleGouden medailleGouden medailleGouden medaille

-1
Opgelost met een tip op stackoverflow.

eerst : Database access : items = List(Of BlogPost)
nu : Database access : items = ProfelSortableList(Of BlogPost)

  1. Imports System.ComponentModel
  2. Imports System.Linq.Expressions
  3.  
  4. Namespace ProfelFramework.Common
  5.  
  6. Public Class ProfelSortableList(Of T)
  7. Inherits System.ComponentModel.BindingList(Of T)
  8.  
  9. Private originalList As List(Of T)
  10. Private sortDirection As ListSortDirection
  11. Private sortProperty As PropertyDescriptor
  12.  
  13. Private populateBaseList As Action(Of ProfelSortableList(Of T), List(Of T)) = Sub(a, b) a.ResetItems(b)
  14.  
  15. Shared cachedOrderByExpressions As New Dictionary(Of String, Func(Of List(Of T), IEnumerable(Of T)))()
  16.  
  17. Protected Overrides ReadOnly Property SupportsSortingCore() As Boolean
  18. Get
  19. Return True
  20. End Get
  21. End Property
  22.  
  23. Protected Overrides ReadOnly Property SortDirectionCore() As ListSortDirection
  24. Get
  25. Return sortDirection
  26. End Get
  27. End Property
  28.  
  29. Protected Overrides ReadOnly Property SortPropertyCore() As PropertyDescriptor
  30. Get
  31. Return sortProperty
  32. End Get
  33. End Property
  34.  
  35. Public Sub New()
  36. originalList = New List(Of T)()
  37. End Sub
  38.  
  39. Public Sub New(ByVal enumerable As IEnumerable(Of T))
  40. originalList = enumerable.ToList()
  41. populateBaseList(Me, originalList)
  42. End Sub
  43.  
  44. Public Sub New(ByVal list As List(Of T))
  45. originalList = list
  46. populateBaseList(Me, originalList)
  47. End Sub
  48.  
  49. Protected Overrides Sub ApplySortCore(ByVal prop As PropertyDescriptor, ByVal direction As ListSortDirection)
  50. sortProperty = prop
  51.  
  52. Dim orderByMethodName = If(sortDirection = ListSortDirection.Ascending, "OrderBy", "OrderByDescending")
  53. Dim cacheKey = Convert.ToString(GetType(T).GUID.ToString & prop.Name) & orderByMethodName
  54.  
  55. If Not cachedOrderByExpressions.ContainsKey(cacheKey) Then
  56. CreateOrderByMethod(prop, orderByMethodName, cacheKey)
  57. End If
  58.  
  59. ResetItems(cachedOrderByExpressions(cacheKey)(originalList).ToList())
  60. ResetBindings()
  61. sortDirection = If(sortDirection = ListSortDirection.Ascending, ListSortDirection.Descending, ListSortDirection.Ascending)
  62. End Sub
  63.  
  64. Private Sub CreateOrderByMethod(ByVal prop As PropertyDescriptor, ByVal orderByMethodName As String, ByVal cacheKey As String)
  65. Dim sourceParameter = Expression.Parameter(GetType(List(Of T)), "source")
  66. Dim lambdaParameter = Expression.Parameter(GetType(T), "lambdaParameter")
  67. Dim accesedMember = GetType(T).GetProperty(prop.Name)
  68. Dim propertySelectorLambda = Expression.Lambda(Expression.MakeMemberAccess(lambdaParameter, accesedMember), lambdaParameter)
  69. Dim orderByMethod = GetType(Enumerable).GetMethods().Where(Function(a) a.Name = orderByMethodName AndAlso a.GetParameters().Length = 2).[Single]().MakeGenericMethod(GetType(T), prop.PropertyType)
  70.  
  71. Dim orderByExpression = Expression.Lambda(Of Func(Of List(Of T), IEnumerable(Of T)))(Expression.[Call](orderByMethod, New Expression() {sourceParameter, propertySelectorLambda}), sourceParameter)
  72.  
  73. cachedOrderByExpressions.Add(cacheKey, orderByExpression.Compile())
  74. End Sub
  75.  
  76. Protected Overrides Sub RemoveSortCore()
  77. ResetItems(originalList)
  78. End Sub
  79.  
  80. Private Sub ResetItems(ByVal items As List(Of T))
  81. MyBase.ClearItems()
  82.  
  83. For i As Integer = 0 To items.Count - 1
  84. MyBase.InsertItem(i, items(i))
  85. Next
  86. End Sub
  87.  
  88. Protected Overrides Sub OnListChanged(ByVal e As ListChangedEventArgs)
  89. originalList = MyBase.Items.ToList()
  90. End Sub
  91.  
  92. End Class
  93.  
  94. End Namespace
Gesponsorde links
Je moet ingelogd zijn om een reactie te kunnen posten.
Actieve forumberichten
© 2002-2024 Sitemasters.be - Regels - Laadtijd: 0.179s