将SortedList绑定为数据源到我的DataGridView

时间:2016-06-04 11:25:58

标签: vb.net datagridview bindingsource sortedlist

美好的一天,

我有一个课程,我每个月计算一次抵押贷款。在这个课程中,我有一个数据结构,我在其中存储每个抵押支付的属性,这些属性是在循环中计算的。然后我有SortedList,我存储每笔抵押贷款。在类中,我有一个返回此SortedList的函数。

在我的用户界面中,我调用返回SortedList的函数并将其绑定到DataSource。我将此DataSource设置为DataGridView,但是当我执行该程序时,DataGridView只显示没有值的空白行。

这是我的班级(称为摊销)

在结束函数之后我调用了函数

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

2 个答案:

答案 0 :(得分:1)

SortedList不是DataGridView的合适数据源。列表中的每个项目都是KeyValuePair,因此网格只能显示StringKey的{​​{1}}个表示形式。如果您希望看到Value对象的属性,则必须绑定MonthlyPeriod个对象的列表。您可以从MonthlyPeriod的{​​{1}}属性中获取该内容。

答案 1 :(得分:0)

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类

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>$300,000.00</amount>
        '  <term>360</term>
        '  <rate>3.73 %</rate>
        '  <payment>$1,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文件之间的贷款。