将 SortedList 作为数据源绑定到我的 DataGridView
Binding a SortedList as a Data Source to my DataGridView
美好的一天,
我有一个 class 可以计算每个月的抵押贷款付款额。在这个 class 中,我有一个数据结构,我在其中存储每个抵押付款的属性,这些属性是在循环中计算的。然后我有 SortedList,我在其中存储每笔抵押贷款付款。在 class 中,我有一个 returns 这个 SortedList.
的函数
在我的用户界面中,我调用 returns SortedList 并将其绑定到 DataSource 的函数。我将这个DataSource设置为DataGridView,但是当我执行程序时,DataGridView只显示没有值的空白行。
这是我的 classs(称为摊销)
End Function 之后是我对函数的调用
Public Function GetMonthlyPaymentDetails() As SortedList(Of Integer, MonthlyPeriod)
Dim counter As Integer = 1
Period.PaymentDate = Today
Period.CumulativeInterest = 0
Period.EndingBalance = Principal
Period.ScheduledPayment = ComputeScheduledPayment()
Do
Period.BeginningBalance = Period.EndingBalance
Period.Interest = GetInterestPerPayment(Period.BeginningBalance)
Period.Principal = GetPrincipalPerPayment(Period.ScheduledPayment, Period.Interest)
Period.EndingBalance = GetEndingBalance(Period.BeginningBalance, Period.Principal)
Period.CumulativeInterest = AccumilateInterest(Period.CumulativeInterest, Period.Interest)
'ArrayPeriod(counter) = Period
ArrayPeriod.Add(counter, Period)
counter += 1
'Loop Until Period.EndingBalance = 0
Loop Until counter = 240
Return ArrayPeriod
End Function
如何调用函数
Dim ABindingSource As New BindingSource
a.GetMonthlyPaymentDetails()
ABindingSource.DataSource = a.ArrayPeriod
AmortizationGrid.DataSource = ABindingSource
SortedList
不是 DataGridView
的合适数据源。列表中的每一项都是一个 KeyValuePair
,因此网格只能显示 Key
和 Value
的 String
表示。如果您希望看到 MonthlyPeriod
个对象的属性,那么您必须绑定 MonthlyPeriod
个对象的列表。您可以从 SortedList
.
的 Values
属性 中获取
jmcilhinney 给出了很好的答案。 FWIW,我有一个简单的贷款计算器的代码,我想我会分享。这是它的测试方式
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim foo As New LoanCalc(300000, 3.73D, 360)
DataGridView1.DataSource = foo.Schedule
End Sub
这是 LoanCalc class
Public Class LoanCalc
'payment
' iA
' P = ------------
' 1-((1+i)^-n)
'
'
'loan balance after n paymnets
'Balance = A(1+i)^n-P/i((1+i)^n-1)
'
'P is payment, i is interest rate, A is loan amount, n is the number of payments
Private _amt As Decimal = 0 'loan amount
Private _term As Integer = 0 'term of loan in months
Private _rate As Decimal = 0 'interest rate / period (rate / 12)
Private _payment As Decimal = 0 'payment
Private Shared ReadOnly zeroPercent As Decimal = 1D / 1000000000 'a kludge
''' <summary>
''' create loan object
''' </summary>
''' <param name="loanmAmt">the amount of the loan</param>
''' <param name="interestRate">interest rate, e.g. 4.5 or .045 for 4.5%</param>
''' <param name="TermMonths">loan length in months</param>
''' <remarks></remarks>
Public Sub New(loanmAmt As String, interestRate As String, TermMonths As String)
Me._amt = Decimal.Parse(loanmAmt)
Dim r As Decimal = Decimal.Parse(interestRate)
If r >= 1 Then
Me._rate = r / 100D
Else
Me._rate = r
End If
Me._rate /= 12D
If Me._rate = 0D Then Me._rate = zeroPercent
Me._term = Integer.Parse(TermMonths)
Me._payment = CDec(-((Me._rate * Me._amt) / (1 - ((1 + Me._rate) ^ -Me._term))))
End Sub
''' <summary>
''' create loan object
''' </summary>
''' <param name="loanmAmt">the amount of the loan</param>
''' <param name="interestRate">interest rate, e.g. 4.5 or .045 for 4.5%</param>
''' <param name="TermMonths">loan length in months</param>
''' <remarks></remarks>
Public Sub New(loanmAmt As Decimal, interestRate As Decimal, TermMonths As Integer)
Me._amt = loanmAmt
If interestRate >= 1 Then
Me._rate = interestRate / 100D
Else
Me._rate = interestRate
End If
Me._rate /= 12D
If Me._rate = 0D Then Me._rate = zeroPercent
Me._term = TermMonths
Me._payment = CDec(-((Me._rate * Me._amt) / (1 - ((1 + Me._rate) ^ -Me._term))))
End Sub
Public Function LoanAmount() As Decimal
Return Me._amt
End Function
Public Function InterestRate() As Decimal
Return Me._rate * 12D
End Function
Public Function TermMonths() As Decimal
Return Me._term
End Function
Public Function TermYears() As Decimal
Return Me._term / 12D
End Function
Public Function Payment() As Decimal
Return Me._payment
End Function
Public Function Schedule() As DataTable
Me.LOANxml = New XElement(Me.loanCont)
Me.LOANxml.<loaninfo>.<name>.Value = Me.NameOfLoan
Me.LOANxml.<loaninfo>.<amount>.Value = Me._amt.ToString("c2")
Me.LOANxml.<loaninfo>.<term>.Value = Me._term.ToString
Me.LOANxml.<loaninfo>.<rate>.Value = (Me._rate * 12D).ToString("p4")
Me.LOANxml.<loaninfo>.<payment>.Value = (-Me._payment).ToString
Dim amort As New XElement(Me.loanAmort)
Dim begbal As Decimal = Me._amt
Dim pad As Integer = Me._term.ToString.Length
For np As Integer = 1 To Me._term
Dim balAfter As Decimal = Me.BalanceAfterXpayments(np)
Dim prin As Decimal = begbal - balAfter
Dim int As Decimal = -Me._payment - prin
Dim apay As New XElement(loanSched)
apay.<num>.Value = np.ToString.PadLeft(pad, " "c) 'make payment number sortable
apay.<begbal>.Value = begbal.ToString("c2")
apay.<interest>.Value = int.ToString("c2")
apay.<principal>.Value = prin.ToString("c2")
apay.<endbal>.Value = balAfter.ToString("c2")
amort.Add(apay)
begbal = balAfter
Next
Me.LOANxml.Add(amort)
Dim tempDS As New DataSet
tempDS.ReadXml(amort.CreateReader)
' Me.PopulateLoanInfo(Me.LOANxml) 'for testing XML
Return tempDS.Tables(0).Copy
End Function
Private Function BalanceAfterXpayments(numOfPaymnets As Integer) As Decimal
'Balance = A(1+i)^n-P/i((1+i)^n-1)
Dim onePlusIupN As Double = (1 + Me._rate) ^ numOfPaymnets
Return CDec((Me._amt * onePlusIupN) - ((-Me._payment / Me._rate) * (onePlusIupN - 1)))
End Function
Public NameOfLoan As String
Private LOANxml As XElement
Private loanCont As XElement = <loan>
<loaninfo>
<name></name>
<amount></amount>
<term></term>
<rate></rate>
<payment></payment>
</loaninfo>
<!-- schedule follows -->
</loan>
Private loanAmort As XElement = <amortization>
</amortization>
Private loanSched As XElement = <sched>
<num></num>
<begbal></begbal>
<interest></interest>
<principal></principal>
<endbal></endbal>
</sched>
Public Sub SaveScheduleXML(path As String)
If Me.LOANxml IsNot Nothing Then
Me.LOANxml.Save(path)
End If
End Sub
Public Sub LoadXMLLoan(path As String)
Dim xe As XElement = XElement.Load(path)
Me.PopulateLoanInfo(xe)
End Sub
Private Sub PopulateLoanInfo(theLoan As XElement)
'sample
'
'<loaninfo>
' <name>Test this</name>
' <amount>0,000.00</amount>
' <term>360</term>
' <rate>3.73 %</rate>
' <payment>,385.94</payment>
'</loaninfo>
Me.NameOfLoan = theLoan.<loaninfo>.<name>.Value
Me._amt = Decimal.Parse(theLoan.<loaninfo>.<amount>.Value.Replace("$", "").Replace(",", ""))
Me._term = Integer.Parse(theLoan.<loaninfo>.<term>.Value)
Me._rate = Decimal.Parse(theLoan.<loaninfo>.<rate>.Value.Replace("%", "").Trim)
Me._rate /= 100D 'convert rate from percent
Me._rate /= 12D 'and then monthly
If Me._rate = 0D Then Me._rate = zeroPercent
Me._payment = Decimal.Parse(theLoan.<loaninfo>.<payment>.Value.Replace("$", "").Replace(",", ""))
Me._payment = -Me._payment
End Sub
End Class
这有用于保存借入和借出 XML 个文件的代码。
美好的一天,
我有一个 class 可以计算每个月的抵押贷款付款额。在这个 class 中,我有一个数据结构,我在其中存储每个抵押付款的属性,这些属性是在循环中计算的。然后我有 SortedList,我在其中存储每笔抵押贷款付款。在 class 中,我有一个 returns 这个 SortedList.
的函数在我的用户界面中,我调用 returns SortedList 并将其绑定到 DataSource 的函数。我将这个DataSource设置为DataGridView,但是当我执行程序时,DataGridView只显示没有值的空白行。
这是我的 classs(称为摊销)
End Function 之后是我对函数的调用
Public Function GetMonthlyPaymentDetails() As SortedList(Of Integer, MonthlyPeriod)
Dim counter As Integer = 1
Period.PaymentDate = Today
Period.CumulativeInterest = 0
Period.EndingBalance = Principal
Period.ScheduledPayment = ComputeScheduledPayment()
Do
Period.BeginningBalance = Period.EndingBalance
Period.Interest = GetInterestPerPayment(Period.BeginningBalance)
Period.Principal = GetPrincipalPerPayment(Period.ScheduledPayment, Period.Interest)
Period.EndingBalance = GetEndingBalance(Period.BeginningBalance, Period.Principal)
Period.CumulativeInterest = AccumilateInterest(Period.CumulativeInterest, Period.Interest)
'ArrayPeriod(counter) = Period
ArrayPeriod.Add(counter, Period)
counter += 1
'Loop Until Period.EndingBalance = 0
Loop Until counter = 240
Return ArrayPeriod
End Function
如何调用函数
Dim ABindingSource As New BindingSource
a.GetMonthlyPaymentDetails()
ABindingSource.DataSource = a.ArrayPeriod
AmortizationGrid.DataSource = ABindingSource
SortedList
不是 DataGridView
的合适数据源。列表中的每一项都是一个 KeyValuePair
,因此网格只能显示 Key
和 Value
的 String
表示。如果您希望看到 MonthlyPeriod
个对象的属性,那么您必须绑定 MonthlyPeriod
个对象的列表。您可以从 SortedList
.
Values
属性 中获取
jmcilhinney 给出了很好的答案。 FWIW,我有一个简单的贷款计算器的代码,我想我会分享。这是它的测试方式
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim foo As New LoanCalc(300000, 3.73D, 360)
DataGridView1.DataSource = foo.Schedule
End Sub
这是 LoanCalc class
Public Class LoanCalc
'payment
' iA
' P = ------------
' 1-((1+i)^-n)
'
'
'loan balance after n paymnets
'Balance = A(1+i)^n-P/i((1+i)^n-1)
'
'P is payment, i is interest rate, A is loan amount, n is the number of payments
Private _amt As Decimal = 0 'loan amount
Private _term As Integer = 0 'term of loan in months
Private _rate As Decimal = 0 'interest rate / period (rate / 12)
Private _payment As Decimal = 0 'payment
Private Shared ReadOnly zeroPercent As Decimal = 1D / 1000000000 'a kludge
''' <summary>
''' create loan object
''' </summary>
''' <param name="loanmAmt">the amount of the loan</param>
''' <param name="interestRate">interest rate, e.g. 4.5 or .045 for 4.5%</param>
''' <param name="TermMonths">loan length in months</param>
''' <remarks></remarks>
Public Sub New(loanmAmt As String, interestRate As String, TermMonths As String)
Me._amt = Decimal.Parse(loanmAmt)
Dim r As Decimal = Decimal.Parse(interestRate)
If r >= 1 Then
Me._rate = r / 100D
Else
Me._rate = r
End If
Me._rate /= 12D
If Me._rate = 0D Then Me._rate = zeroPercent
Me._term = Integer.Parse(TermMonths)
Me._payment = CDec(-((Me._rate * Me._amt) / (1 - ((1 + Me._rate) ^ -Me._term))))
End Sub
''' <summary>
''' create loan object
''' </summary>
''' <param name="loanmAmt">the amount of the loan</param>
''' <param name="interestRate">interest rate, e.g. 4.5 or .045 for 4.5%</param>
''' <param name="TermMonths">loan length in months</param>
''' <remarks></remarks>
Public Sub New(loanmAmt As Decimal, interestRate As Decimal, TermMonths As Integer)
Me._amt = loanmAmt
If interestRate >= 1 Then
Me._rate = interestRate / 100D
Else
Me._rate = interestRate
End If
Me._rate /= 12D
If Me._rate = 0D Then Me._rate = zeroPercent
Me._term = TermMonths
Me._payment = CDec(-((Me._rate * Me._amt) / (1 - ((1 + Me._rate) ^ -Me._term))))
End Sub
Public Function LoanAmount() As Decimal
Return Me._amt
End Function
Public Function InterestRate() As Decimal
Return Me._rate * 12D
End Function
Public Function TermMonths() As Decimal
Return Me._term
End Function
Public Function TermYears() As Decimal
Return Me._term / 12D
End Function
Public Function Payment() As Decimal
Return Me._payment
End Function
Public Function Schedule() As DataTable
Me.LOANxml = New XElement(Me.loanCont)
Me.LOANxml.<loaninfo>.<name>.Value = Me.NameOfLoan
Me.LOANxml.<loaninfo>.<amount>.Value = Me._amt.ToString("c2")
Me.LOANxml.<loaninfo>.<term>.Value = Me._term.ToString
Me.LOANxml.<loaninfo>.<rate>.Value = (Me._rate * 12D).ToString("p4")
Me.LOANxml.<loaninfo>.<payment>.Value = (-Me._payment).ToString
Dim amort As New XElement(Me.loanAmort)
Dim begbal As Decimal = Me._amt
Dim pad As Integer = Me._term.ToString.Length
For np As Integer = 1 To Me._term
Dim balAfter As Decimal = Me.BalanceAfterXpayments(np)
Dim prin As Decimal = begbal - balAfter
Dim int As Decimal = -Me._payment - prin
Dim apay As New XElement(loanSched)
apay.<num>.Value = np.ToString.PadLeft(pad, " "c) 'make payment number sortable
apay.<begbal>.Value = begbal.ToString("c2")
apay.<interest>.Value = int.ToString("c2")
apay.<principal>.Value = prin.ToString("c2")
apay.<endbal>.Value = balAfter.ToString("c2")
amort.Add(apay)
begbal = balAfter
Next
Me.LOANxml.Add(amort)
Dim tempDS As New DataSet
tempDS.ReadXml(amort.CreateReader)
' Me.PopulateLoanInfo(Me.LOANxml) 'for testing XML
Return tempDS.Tables(0).Copy
End Function
Private Function BalanceAfterXpayments(numOfPaymnets As Integer) As Decimal
'Balance = A(1+i)^n-P/i((1+i)^n-1)
Dim onePlusIupN As Double = (1 + Me._rate) ^ numOfPaymnets
Return CDec((Me._amt * onePlusIupN) - ((-Me._payment / Me._rate) * (onePlusIupN - 1)))
End Function
Public NameOfLoan As String
Private LOANxml As XElement
Private loanCont As XElement = <loan>
<loaninfo>
<name></name>
<amount></amount>
<term></term>
<rate></rate>
<payment></payment>
</loaninfo>
<!-- schedule follows -->
</loan>
Private loanAmort As XElement = <amortization>
</amortization>
Private loanSched As XElement = <sched>
<num></num>
<begbal></begbal>
<interest></interest>
<principal></principal>
<endbal></endbal>
</sched>
Public Sub SaveScheduleXML(path As String)
If Me.LOANxml IsNot Nothing Then
Me.LOANxml.Save(path)
End If
End Sub
Public Sub LoadXMLLoan(path As String)
Dim xe As XElement = XElement.Load(path)
Me.PopulateLoanInfo(xe)
End Sub
Private Sub PopulateLoanInfo(theLoan As XElement)
'sample
'
'<loaninfo>
' <name>Test this</name>
' <amount>0,000.00</amount>
' <term>360</term>
' <rate>3.73 %</rate>
' <payment>,385.94</payment>
'</loaninfo>
Me.NameOfLoan = theLoan.<loaninfo>.<name>.Value
Me._amt = Decimal.Parse(theLoan.<loaninfo>.<amount>.Value.Replace("$", "").Replace(",", ""))
Me._term = Integer.Parse(theLoan.<loaninfo>.<term>.Value)
Me._rate = Decimal.Parse(theLoan.<loaninfo>.<rate>.Value.Replace("%", "").Trim)
Me._rate /= 100D 'convert rate from percent
Me._rate /= 12D 'and then monthly
If Me._rate = 0D Then Me._rate = zeroPercent
Me._payment = Decimal.Parse(theLoan.<loaninfo>.<payment>.Value.Replace("$", "").Replace(",", ""))
Me._payment = -Me._payment
End Sub
End Class
这有用于保存借入和借出 XML 个文件的代码。