Reputation: 555
I am learning to create custom class and collection class. Now to put my newly learned skills to the test, I would like to display the collection class in a datagridview
object.
If I set the collection class as datasource
, no data is populated in the datagridview
..
My sample contains a purchase class object containing some properties. The purchases are collected in one collect class called purchases.
The datagridview should show all purchases in the collection to the user.
Below is my code.
Public Class PurchasesEditor
Private Property Purchases As New Purchases
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Dim oPurchase As New Purchase
oPurchase.ID = Purchases.Count + 1
oPurchase.Description = "Test item"
oPurchase.Supplier = "Wallmart"
oPurchase.PurchaseDate = "13/09/2018"
oPurchase.VAT = 21
oPurchase.Amount = 100
Purchases.Add(oPurchase)
dgvPurchases.DataSource = Purchases
End Sub
End Class
Purchases collection class Public Class Purchases
Private PurchaseList As New List(Of Purchase)
Public Sub Add(purchase As Purchase)
PurchaseList.Add(purchase)
End Sub
Public Function Remove(purchase As Purchase) As Boolean
Return PurchaseList.Remove(purchase)
End Function
Public Function GetEnumerator() As IEnumerator(Of Purchase)
Return PurchaseList.GetEnumerator
End Function
Public ReadOnly Property Count() As Integer
Get
Return PurchaseList.Count
End Get
End Property
End Class
Purchase class Public Class Purchase
Public Property ID As Long
Public Property Description As String
Public Property Supplier As String
Public Property PurchaseDate As Date
Public Property Amount As Decimal
Public Property VAT As Double
Public ReadOnly Property VATamount As Decimal
Get
Return Amount + Amount * (VAT / 100)
End Get
End Property
' TODO custom collection
'Public Property AttachedDocuments As List(Of Document)
End Class
Upvotes: 0
Views: 625
Reputation: 54457
The problem is that your Purchases
class is NOT a collection. It CONTAINS a collection, i.e. the List(Of Purchase)
you assign to the PurchaseList
field, but that is hidden inside. The DataGridView
won't magically get at that data and display it.
In order for your class to be a list/collection then, at the very least, it must implement the IEnumerable
and/or IEnumerable(Of T)
interface. You can also implement ICollection
and/or ICollection(Of T)
, which extend the previous interfaces. You can also implement IList
and/or IList(Of T)
, which extend the previous interfaces even further. In order to be useful in binding to a DataGridView
you would need to implement IList
and you should implement IList(Of T)
too.
You can implement those interfaces from scratch if you want but you shouldn't. The System.Collections.ObjectModel.Collection(Of T)
class provides a base implementation of IList
and IList(Of T)
that you can extend by inheriting and then overriding and/or adding your own functionality. If you are aiming to bind specifically then you should instead inherit the System.ComponentModel.BindingList(Of T)
class, which inherits Collection(Of T)
and adds specific binding support by implementing the IBindingList
interface. If you need filtering functionality too then you can implement the IBindingListView
interface as well.
Unless you need specific custom functionality, you should just stick with the List(Of T)
. If you use one in data-binding scenarios though, it doesn't raise the events required for the UI to update on changes. In that case, you can bind the list to a BindingSource
and bind that to your UI, then call methods like ResetBindings
as required to update the UI.
I suggest that you read this for more detailed information.
Upvotes: 4