VB.Net循环创建事件时弹窗始终显示最后一个值求助
问题原因
这是VB.NET中闭包捕获变量的典型问题:你在事件处理的匿名方法里引用的menuName是循环外层的变量,闭包捕获的是变量的引用而非当前迭代的具体值。当循环结束后,menuName的值停留在最后一次迭代的结果,所有TreeViewItem的双击事件触发时,都会读取这个最终值。
解决方法
有两种常用的修复方式:
方法1:在循环内部创建局部变量保存当前值
在每次循环迭代中,声明一个局部变量来存储当前的menuName,让闭包捕获这个局部变量(每个迭代的局部变量是独立的实例):
While tb.MoveNext() Try idMenu = tb.Current.Field(Of Integer)("idMenu") menuName = tb.Current.Field(Of String)("HeaderName") ClassType = tb.Current?.Field(Of String)("ClassType") newTreeItem = New TreeViewItem() ' 声明局部变量保存当前迭代的menuName Dim currentMenuName = menuName Dim clickHandler As New MouseButtonEventHandler(Sub(sender, e) MessageBox.Show(currentMenuName) End Sub) AddHandler newTreeItem.PreviewMouseDoubleClick, clickHandler Catch ex As Exception End Try End While
方法2:将menuName绑定到TreeViewItem的Tag属性
把当前的menuName赋值给TreeViewItem的Tag属性,在事件处理中从触发事件的控件上获取这个值:
While tb.MoveNext() Try idMenu = tb.Current.Field(Of Integer)("idMenu") menuName = tb.Current.Field(Of String)("HeaderName") ClassType = tb.Current?.Field(Of String)("ClassType") newTreeItem = New TreeViewItem() ' 将menuName存入Tag newTreeItem.Tag = menuName Dim clickHandler As New MouseButtonEventHandler(Sub(sender, e) Dim item = TryCast(sender, TreeViewItem) If item IsNot Nothing Then MessageBox.Show(item.Tag.ToString()) End If End Sub) AddHandler newTreeItem.PreviewMouseDoubleClick, clickHandler Catch ex As Exception End Try End While
额外提示:代码里TryCast(newTreeItem, TreeViewItem)是多余的,因为newTreeItem本身就是TreeViewItem实例,可以直接使用。
内容的提问来源于stack exchange,提问作者DevGold
相关产品推荐
相关产品推荐

