VB.NET 上下文菜单中的 Lambda 表达式得到错误的项目
VB.NET Lambda expression in contextmenu getting wrong item
如果有人能阐明问题,我将不胜感激。
我有一个显示销售订单的表格,其中有一个 DGV (DGVDocs) 显示该订单的发票清单。我用文档填充了一个打印按钮,并为每个子菜单填充了打印、预览、PDF。子菜单上的 lambda 表达式总是选取菜单上的最后一个条目。
Private Sub create_print_menu()
Dim i As Integer = 0
ms = New ContextMenuStrip
If dgvDocs.Rows.Count > 0 Then
Dim doctype As String = ""
Dim docno As Integer = 0
For i = 0 To dgvDocs.Rows.Count - 1
ms.Items.Add(RTrim(dgvDocs.Rows(i).Cells(0).Value) & " " & RTrim(dgvDocs.Rows(i).Cells(2).Value))
jc = ms.Items(ms.Items.Count - 1)
doctype = RTrim(dgvDocs.Rows(i).Cells(0).Value)
docno = RTrim(dgvDocs.Rows(i).Cells(2).Value)
jc.DropDownItems.Add("Preview", Nothing, Function(sender, e) docPreview(doctype, docno))
Next
End If
End Sub
Private Function docPreview(ByVal doctype As String, ByVal docno As Integer)
If doctype.ToUpper.Contains("DESPATCH NOTE") Then
Dim frm As New frmDespatchPreview
frm.delnote = docno
frm.ShowDialog()
ElseIf doctype.ToUpper.Contains("INVOICE") Then
Dim frm As New frmInvoicePreview
frm.invno = docno
frm.ShowDialog()
End If
Return True
Return True
End Function
当您在循环中传递 lambda 时:
Function(sender, e) docPreview(doctype, docno)
...您不会传入 copy 或 snapshot doctype
和 docno
在该特定循环迭代时。您实际上是在传递对这些变量的引用。
因此,在循环结束时,所有 lambda 表达式都将有效地引用 doctype
和 docno
的最后一个值。
为避免此问题,请确保每个 lambda 都引用一个不同的 变量引用。这可以通过在 循环中声明 doctype
和 docno
来实现,如下所示:
'Dim doctype As String = ""
'Dim docno As Integer = 0
For i = 0 To dgvDocs.Rows.Count - 1
ms.Items.Add(RTrim(dgvDocs.Rows(i).Cells(0).Value) & " " & RTrim(dgvDocs.Rows(i).Cells(2).Value))
jc = ms.Items(ms.Items.Count - 1)
Dim doctype As String = RTrim(dgvDocs.Rows(i).Cells(0).Value)
Dim docno As Integer = RTrim(dgvDocs.Rows(i).Cells(2).Value)
jc.DropDownItems.Add("Preview", Nothing, Function(sender, e) docPreview(doctype, docno))
Next
编辑:
如果有人能阐明问题,我将不胜感激。 我有一个显示销售订单的表格,其中有一个 DGV (DGVDocs) 显示该订单的发票清单。我用文档填充了一个打印按钮,并为每个子菜单填充了打印、预览、PDF。子菜单上的 lambda 表达式总是选取菜单上的最后一个条目。
Private Sub create_print_menu()
Dim i As Integer = 0
ms = New ContextMenuStrip
If dgvDocs.Rows.Count > 0 Then
Dim doctype As String = ""
Dim docno As Integer = 0
For i = 0 To dgvDocs.Rows.Count - 1
ms.Items.Add(RTrim(dgvDocs.Rows(i).Cells(0).Value) & " " & RTrim(dgvDocs.Rows(i).Cells(2).Value))
jc = ms.Items(ms.Items.Count - 1)
doctype = RTrim(dgvDocs.Rows(i).Cells(0).Value)
docno = RTrim(dgvDocs.Rows(i).Cells(2).Value)
jc.DropDownItems.Add("Preview", Nothing, Function(sender, e) docPreview(doctype, docno))
Next
End If
End Sub
Private Function docPreview(ByVal doctype As String, ByVal docno As Integer)
If doctype.ToUpper.Contains("DESPATCH NOTE") Then
Dim frm As New frmDespatchPreview
frm.delnote = docno
frm.ShowDialog()
ElseIf doctype.ToUpper.Contains("INVOICE") Then
Dim frm As New frmInvoicePreview
frm.invno = docno
frm.ShowDialog()
End If
Return True
Return True
End Function
当您在循环中传递 lambda 时:
Function(sender, e) docPreview(doctype, docno)
...您不会传入 copy 或 snapshot doctype
和 docno
在该特定循环迭代时。您实际上是在传递对这些变量的引用。
因此,在循环结束时,所有 lambda 表达式都将有效地引用 doctype
和 docno
的最后一个值。
为避免此问题,请确保每个 lambda 都引用一个不同的 变量引用。这可以通过在 循环中声明 doctype
和 docno
来实现,如下所示:
'Dim doctype As String = ""
'Dim docno As Integer = 0
For i = 0 To dgvDocs.Rows.Count - 1
ms.Items.Add(RTrim(dgvDocs.Rows(i).Cells(0).Value) & " " & RTrim(dgvDocs.Rows(i).Cells(2).Value))
jc = ms.Items(ms.Items.Count - 1)
Dim doctype As String = RTrim(dgvDocs.Rows(i).Cells(0).Value)
Dim docno As Integer = RTrim(dgvDocs.Rows(i).Cells(2).Value)
jc.DropDownItems.Add("Preview", Nothing, Function(sender, e) docPreview(doctype, docno))
Next
编辑: