在 FlowLayoutPanel 中的 UserControl 中处理控件的值更改



我正在制作发票申请。我在 FlowLayoutPanel (pnlEntries( 的用户控件 (InvoiceEntry( 内有一个标签 (lblCost(。InvoiceEntry 表示发票上的行项目,pnlEntries 是发票的"正文"。pnlEntries 可以容纳多个 InvoiceEntry 控件。

我正在尝试对每个 InvoiceEntry 控件中的所有 lblCost 值求和以生成小计,并且我希望该小计在成本更改时自动更改(例如,订购数量的变化(。有没有办法处理 pnlEntries 中包含的任何 InvoiceEntry 控件的 lblCost.Text 属性更改?

发票添加.vb:

' Instantiate objects of the various database interaction classes.
Private mCustomer As New Customers
Private mItem As New Items
Private mInvoices As New Invoices
Private mInvoiceItem As New InvoiceItems
' An array of InvoiceEntries for DB processing
Private Entries() As InvoiceEntry
Private numEntries As Integer = 0
Private Sub InvoiceAdd_Load(sender As System.Object, e As System.EventArgs) _
            Handles MyBase.Load
    Me.CustomersTableAdapter.Fill(Me.Bauer_BusinessDataSet.Customers)
    ' Set the DataSource properties of the invEntry control.
    ' NOTE: For some reason, if this is done inside the
    ' control code, the program attempts to look in the
    ' wrong directory for the database. I'm not entirely
    ' sure why this is. Setting these properties in the form code,
    ' rather than in the control code, is a successful workaround.
    With invEntry.cboItem
        .DataSource = mItem.Items
        .DisplayMember = "ItemName"
        .ValueMember = "Id"
    End With
End Sub
Private Sub UpdateTotal() Handles nudTaxRate.TextChanged, _
                                  pnlEntries.GotFocus
    Dim total As Decimal = 0
    If Entries IsNot Nothing Then
        For Each x In Entries
            total += CDec(x.lblTotal.Text)
        Next
        lblSubtotal.Text = total.ToString("C")
        lblTax.Text = (lblSubtotal.Text * (nudTaxRate.Text / 100)).ToString("C")
        Dim subtotal As Decimal = 0
        Dim tax As Decimal = 0
        If Not lblSubtotal.Text = Nothing And Not lblTax.Text = Nothing Then
            Decimal.TryParse(lblSubtotal.Text.Substring(1), subtotal)
            Decimal.TryParse(lblTax.Text.Substring(1), tax)
        End If
        lblGrandTotal.Text = (subtotal + tax).ToString("C")
    End If
End Sub
Public Sub invEntry_ItemSelected() Handles invEntry.ItemSelected
    ' Increment the number of entries to reflect the addition of a new entry.
    numEntries += 1
    ' ReDim the Entries array to compensate for a new item being added.
    ReDim Preserve Entries(numEntries - 1)
    ' Store the line item that was selected in the Entries array.
    Entries(numEntries - 1) = invEntry
    ' Set the selected line item to a new blank line item and
    ' add it to the pnlEntries' Controls Collection.
    invEntry = New InvoiceEntry
    With invEntry
        .Name = "Textbox" & numEntries - 1
        .Location = New Point(10, (numEntries - 1) * (.Height + 30))
        With .cboItem
            .DataSource = mItem.Items
            .DisplayMember = "ItemName"
            .ValueMember = "Id"
        End With
    End With
    pnlEntries.Controls.Add(invEntry)
    ' Enable the remove button on the previous list item, as
    ' it is no longer an empty entry.
    Entries(numEntries - 1).btnRemove.Enabled = True
End Sub
Public Sub pnlEntries_ControlRemoved() Handles pnlEntries.ControlRemoved
    numEntries -= 1
    ReDim Preserve Entries(numEntries - 1)
    ' As the Entries array does not know which control was removed,
    ' repopulate it with the controls from the panel.
    ' NOTE: This intentionally leaves the blank line item (invEntry)
    '       out of the array, as this array will be used to add
    '       the invoice line items to the database.
    For x As Integer = 0 To Entries.Count - 1
        Entries(x) = pnlEntries.Controls(x)
    Next
End Sub

发票条目.vb:

' Instantiate an object to interact with the Item table.
Private mItem As New Items
Public Event ItemSelected As EventHandler
Private Sub cboItem_SelectionChangeCommitted(sender As System.Object, _
                    e As System.EventArgs) _
                    Handles cboItem.SelectionChangeCommitted
    RaiseEvent ItemSelected(Me, EventArgs.Empty)
End Sub
Private Sub InvoiceEntry_Load(sender As System.Object, _
                              e As System.EventArgs) _
                              Handles MyBase.Load
    ' Set the various properties of the Item combobox.
    With cboItem
        .SelectedIndex = -1
        .DropDownStyle = ComboBoxStyle.DropDownList
    End With
    ' Set the Remove button to be disabled by default.
    btnRemove.Enabled = False
End Sub
Private Sub cboItem_SelectedIndexChanged(sender As System.Object, _
                    e As System.EventArgs) _
                    Handles cboItem.SelectedIndexChanged
    ' If nothing is selected, clear and disable all relevant controls.
    If cboItem.SelectedIndex = -1 Or cboItem.Text = "" Then
        lblDescription.Text = ""
        lblTotal.Text = ""
        nudQuantity.Enabled = False
        lblPrice.Text = ""
    Else
        ' Else, set the control texts to their respective values.
        lblDescription.Text = _
            cboItem.DataSource.Rows(cboItem.SelectedIndex)("Description")
        lblPrice.Text = cboItem.DataSource.Rows(cboItem.SelectedIndex)("Price")
        lblTotal.Text = (lblPrice.Text * nudQuantity.Value).ToString("C")
        nudQuantity.Enabled = True
    End If
End Sub
Private Sub lblTotal_TextChanged(sender As System.Object, _
                                 e As System.EventArgs) _
                                 Handles lblTotal.TextChanged
    ' This is part of my workaround that I describe in the comments section
    ' of this StackOverflow question.
    Parent.Focus()
End Sub
Private Sub nudQuantity_ValueChanged(sender As System.Object, _
                                     e As System.EventArgs) _
                                     Handles nudQuantity.TextChanged
    ' If the quantity changes, set the total price to reflect this.
    lblTotal.Text = (lblPrice.Text * nudQuantity.Value).ToString("C")
End Sub
Private Sub btnRemove_Click(sender As System.Object, _
                            e As System.EventArgs) _
                            Handles btnRemove.Click
    ' Remove the control from the parent design.
    Me.Parent.Controls.Remove(Me)
End Sub

由于您已经在 InvoiceItem 中获得了 TextChanged 事件处理程序,因此可以轻松地在 InvoiceAdd Form 中调用 UpdateTotal 函数

发票条目.vb

Private Sub lblTotal_TextChanged(sender As System.Object, _
                                 e As System.EventArgs) _
                                 Handles lblTotal.TextChanged
    ' This is part of my workaround that I describe in the comments section
    ' of this StackOverflow question.
    'Parent.Focus()
    'Me.Parent could give you the parent control which is pnlEntry not InvocieAdd form
    'you need to use FindForm here
    Dim MyParentForm As InvoiceAdd = CType(Me.FindForm(), InvoiceAdd)
    MyParentForm.UpdateTotal()
End Sub

发票添加.vb

Public Sub UpdateTotal() Handles nudTaxRate.TextChanged, _
                                  pnlEntries.GotFocus
    'Change the function to Public
    Dim total As Decimal = 0
    If Entries IsNot Nothing Then
        For Each x In Entries
            total += CDec(x.lblTotal.Text)
        Next
        lblSubtotal.Text = total.ToString("C")
        lblTax.Text = (lblSubtotal.Text * (nudTaxRate.Text / 100)).ToString("C")
        Dim subtotal As Decimal = 0
        Dim tax As Decimal = 0
        If Not lblSubtotal.Text = Nothing And Not lblTax.Text = Nothing Then
            Decimal.TryParse(lblSubtotal.Text.Substring(1), subtotal)
            Decimal.TryParse(lblTax.Text.Substring(1), tax)
        End If
        lblGrandTotal.Text = (subtotal + tax).ToString("C")
    End If
End Sub

相关内容

  • 没有找到相关文章