动态生成Button的点击状态串扰问题技术求助
问题根源
你当前代码里用来判断点击状态的clicked是点击事件内的局部变量,每次触发点击都会重新初始化,且没有和具体按钮绑定,导致所有按钮共用错误的状态判断逻辑。另外,依赖集合Maps2Detach的存在性间接判断状态,也会因不同按钮对应相同文件名(若存在)引发串扰。
解决方法
每个按钮的状态需要独立存储,推荐两种简单方案:
方案1:利用按钮的Tag属性存储状态
Tag是WinForm控件的通用属性,可存储任意自定义数据,这里用它保存每个按钮的点击状态:
- 修改按钮创建代码,初始化
Tag为未点击状态:
'Create buttons Dim new_Button As New Button new_Button.Text = NaamX new_Button.Name = CommandX new_Button.Location = New Point(Location_control.X + 10, Location_control.Y) new_Button.Width = 155 Location_control.Y += new_Button.Height + 10 ' 初始化点击状态为未点击 new_Button.Tag = False ' 新增这一行 'Add an action to the button AddHandler new_Button.Click, AddressOf myButtonHandler_Click
- 修改点击事件代码,基于
Tag判断状态并更新:
Public Sub myButtonHandler_Click(ByVal sender As Object, ByVal e As EventArgs) Dim btn = DirectCast(sender, Button) ' 获取当前点击的按钮 MapFile = btn.Name 'Get file details to check the extension FileDetail = My.Computer.FileSystem.GetFileInfo(MapFile) Dim FoundFlag As Integer = 0 Look4File(MapFile, False, FoundFlag) If Not FoundFlag = 1 Then If FileDetail.Extension = ".map" Then ' 从Tag读取当前按钮的点击状态 Dim clicked = CBool(btn.Tag) If Not clicked Then Maps2Detach.Add(MapFile) StartArgument = " ATTACH REFERENCE FILE -F " & " " & Chr(34) & MapFile & Chr(34) ButtonNaam = btn.Text ExecuteTheCommand(CadCommandFile, StartArgument, ButtonNaam) ' 更新状态为已点击 btn.Tag = True Else Maps2Detach.Remove(MapFile) StartArgument = " detach reference file -N " & " " & Chr(34) & MapFile & Chr(34) ButtonNaam = btn.Text ExecuteTheCommand(CadCommandFile, StartArgument, ButtonNaam) ' 更新状态为未点击 btn.Tag = False End If Else ErrorMessage = "Not a MAP file: " & MapFile Log_EveryThing(ErrorMessage) MessageBox.Show(ErrorMessage, "Not a MAP file") End If End If End Sub
方案2:使用字典存储按钮状态
若不想修改控件的Tag,可创建全局字典,以按钮的Name(或按钮对象本身)为键存储对应点击状态:
- 在窗体类中定义全局字典:
Private ButtonClickStates As New Dictionary(Of String, Boolean)
- 创建按钮时初始化字典状态:
'Create buttons Dim new_Button As New Button new_Button.Text = NaamX new_Button.Name = CommandX ' ... 其他按钮属性设置 ' 初始化字典中的状态 ButtonClickStates.Add(new_Button.Name, False)
- 修改点击事件代码:
Public Sub myButtonHandler_Click(ByVal sender As Object, ByVal e As EventArgs) Dim btn = DirectCast(sender, Button) MapFile = btn.Name ' ... 文件检查等逻辑不变 If Not FoundFlag = 1 Then If FileDetail.Extension = ".map" Then Dim clicked = ButtonClickStates(btn.Name) If Not clicked Then ' ATTACH逻辑不变 ButtonClickStates(btn.Name) = True Else ' DETACH逻辑不变 ButtonClickStates(btn.Name) = False End If End If End If End Sub
额外提示
- 添加元素到
Maps2Detach前建议先判断是否已存在,避免重复操作:If Not Maps2Detach.Contains(MapFile) Then Maps2Detach.Add(MapFile) - 若按钮的
Name可能重复(比如XML中有相同的CommandX),建议用按钮对象本身作为字典的键,或给每个按钮分配唯一标识。
内容的提问来源于stack exchange,提问作者Bart Butaye
相关产品推荐
相关产品推荐

