Avatar of Bryant Farley
Bryant Farley
 asked on

Loading items into a collection class

I have a custom object, InvestmentPriceCollection, that is a collection of InvestmentPrice. In a Windows form, I have code that successfully creates a new InvestmentPriceCollection, and by iterating through a gridview, creates new instances of InvestmentPrice (Dim inv as New InvestmentPrice), appending each to InvestmentPriceCollection. This all works great. Naturally, I can't be content with that  :-)

Rather than storing this iteration routine (let's call it LoadFromGridview) at the form level, I'd like to make it more available across the application, and incorporate it into InvestmentPriceCollection. Here's where I run into a problem.

When I create my public function LoadFromGridview in InvestmentPriceCollection, and attempt to define a new InvestmentPrice (Dim inv as New InvestmentPrice), I received the following error:

'New' cannot be used on a type parameter that does not have a 'New' constraint.

I resolved this error by changing the collection class declaration from Public Class InvestmentPriceCollection(Of InvestmentPrice) to:

Public Class InvestmentPriceCollection(Of InvestmentPrice As {New})

But now I'm having problems assigning values to the properties of InvestmentPrice (assume dateparameter is a valid date).

Dim inv as New InvestmentPrice
inv.AsOfDate = dateparameter

The error states that 'AsOfDate' is not a member of 'InvestmentPrice' - but it is! And I've been able to refer to it in the aforementioned form code.

Am I going about this in the wrong way? Will I be able to include LoadFromGridview in the InvestmentPriceCollection object? Is there a better or different way to store it elsewhere in the app?
Visual Basic.NET.NET Programming

Avatar of undefined
Last Comment
Bryant Farley

8/22/2022 - Mon
it_saige

It depends on your implementation of the collection class; e.g. -

Form1.vb -
Public Class Form1
	Private Sub OnLoad(sender As Object, e As EventArgs) Handles MyBase.Load
		If Prices Is Nothing Then
			Prices = New InvestmentPriceCollection(From i In Enumerable.Range(0, 20) Select New InvestmentPrice() With {.ID = i, .Name = String.Format("InvestmentPrice{0}", i), .Price = ((i + 0.2) * 2.6), .AsOfDate = DateTime.Now.AddDays(-(12 * i))})
		End If

		DataGridView1.DataSource = Prices
	End Sub
End Class

Module Globals
	Public Property Prices() As InvestmentPriceCollection
End Module

Class InvestmentPriceCollection
	Inherits List(Of InvestmentPrice)

	Sub New()
		MyBase.New()
	End Sub

	Sub New(capacity As Integer)
		MyBase.New(capacity)
	End Sub

	Sub New(collection As IEnumerable(Of InvestmentPrice))
		MyBase.New(collection)
	End Sub
End Class

Class InvestmentPrice
	Public Property ID() As Integer
	Public Property Name() As String
	Public Property Price() As Decimal
	Public Property AsOfDate() As DateTime
End Class

Open in new window

Form1.Designer.vb -
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
    Inherits System.Windows.Forms.Form

    'Form overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
		Me.DataGridView1 = New System.Windows.Forms.DataGridView()
		CType(Me.DataGridView1, System.ComponentModel.ISupportInitialize).BeginInit()
		Me.SuspendLayout()
		'
		'DataGridView1
		'
		Me.DataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize
		Me.DataGridView1.Dock = System.Windows.Forms.DockStyle.Fill
		Me.DataGridView1.Location = New System.Drawing.Point(0, 0)
		Me.DataGridView1.Name = "DataGridView1"
		Me.DataGridView1.Size = New System.Drawing.Size(470, 261)
		Me.DataGridView1.TabIndex = 0
		'
		'Form1
		'
		Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
		Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
		Me.ClientSize = New System.Drawing.Size(470, 261)
		Me.Controls.Add(Me.DataGridView1)
		Me.Name = "Form1"
		Me.Text = "Form1"
		CType(Me.DataGridView1, System.ComponentModel.ISupportInitialize).EndInit()
		Me.ResumeLayout(False)

	End Sub
	Friend WithEvents DataGridView1 As System.Windows.Forms.DataGridView

End Class

Open in new window

Produces the following output -Capture.JPG
-saige-
ASKER CERTIFIED SOLUTION
Bryant Farley

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
Bryant Farley

ASKER
The user who answered didn't quite understand what I was asking, and in the meantime I'd created a helper class, which works fine.
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy