【问题标题】:Checkbox events when Form is opened and closed fire when form is reloaded重新加载表单时打开和关闭表单时触发的复选框事件
【发布时间】:2013-12-08 02:36:58
【问题描述】:

首先...如果我一开始就做错了,我愿意以不同的方式给这只猫剥皮。使用 VB 2010 .net 4.0,我是个初学者。

我正在制作一个产品计费应用程序,它有一个主表单和一个带有附加选项的子表单。每当打开一次后重新打开该子表单时,选中的复选框事件默认为空白。如果我重新检查它们(以便有人可以取消选中),那么任何重新检查的都会重新启动并再次增加变量。

我最终需要能够在关闭第二个表单后打开它,将之前选中的所有复选框显示为再次选中,并且不增加过程中的变量。

主窗体复选框代码,用于设置布尔值并增加或减少最常用产品的小计变量。

    Private Sub chkbox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkbox1.CheckedChanged
    If chkbox1.Checked = True Then
        bChkbox1 = True
        Subtotal += 15
    Else
        bChkbox1 = False
        Subtotal -= 15
    End If
End Sub

主表单按钮,用于启动列出所有产品的子表单。

    Private Sub btnAllProducts_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAllProducts.Click
    Form3.Show()
End Sub

子表单复选框代码在第一次打开时可以正常工作,但在重新启动时就不行了。

Private Sub chkbox2_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkbox2.CheckedChanged
    If chkbox2.Checked = True Then 'also tried without the nested if with same results
        If Me.IsHandleCreated = True Then 'me.visible behaves the same way
            MsgBox("form visible true")'launches after clicking button but before form is actually on screen
            Form1.bcheckbox2 = True
            Form1.Subtotal += 105
        End If
    Else
        Form1.bcheckbox2 = False
        Form1.Subtotal -= 105
    End If
End Sub

布尔值用于选中在主页上或之前打开时选中的复选框。

    If Form1.bcheckbox2 = True Then
        chkbox2.Checked = True
    End If

正如我所说,如果我这样做是有意义的,我可以完全重写代码,或者如果我犯了某种错误,我可以修复一些东西。

例如,我正在考虑更改以擦除每个表单加载时的小计并根据切换的布尔值重建它,但似乎应该有一种更优雅的方式,开销更少,我只是做错了一些事情。

【问题讨论】:

    标签: vb.net visual-studio-2010 forms checkbox vb.net-2010


    【解决方案1】:

    在加载表单时必须告诉检查和无线电忽略事件并不常见。您只需要一个 Ignore 或 Loaded 标志:

    Public Class Form1
       Private ignore As Boolean = True
       ...
    
     Private Sub Form1_Load(...
        ' do normal stuff
    
        ignore = False               ' should be the ONLY place it is set
     End Sub
    
    Private Sub CheckBox2_CheckedChanged(...
       If ignore Then Exit Sub
    
    End Sub
    

    表单设计器代码将在创建表单和控件时触发事件,这对于初始化内容很方便,但通常会导致麻烦。有些控件甚至会两次获得相同的事件。表单实际上没有“重新加载”操作。如果隐藏它们,Show() 将不会再次触发 Load 事件。

    当表单加载时,您可以避免使用该标志并手动为麻烦的控件添加处理程序,但如果它们很多,这可能会很乏味。标志可以被滥用和误用,但如果它只设置在那个地方,那就没问题了。

    【讨论】:

    • 实例化表单是什么意思?为什么要这样做而不是 .show?
    • 很高兴听到...Form1.Show 是隐式实例化,Dim frm As New Form1 // frm.Show 创建表单的实例,将其视为它们所在的类并从中创建适当的对象。除了明确Class和Object之间的区别之外,它还允许您控制每个表单实例的范围。
    • 啊,所以如果我将选项显式设置为“on”,那么 form1.show 甚至不起作用?既然这是选项显式的推荐设置,我需要在打开它时更改它吗?
    • 不,隐式引用是合法的,只是不建议这样做。一些开发人员甚至不知道存在旧的默认形式(请参阅此处的 cmets:stackoverflow.com/q/20076969/1070452)。使用显式 ref 我可以创建一个 frm 实例并将其显示在我想要的位置,而其他任何东西都无法访问它。默认方法只会导致问题越复杂 - 将这些问题整理出来是这里的常见问题。
    【解决方案2】:

    如果有人正在寻找替代方案或遇到类似问题,这是我检测事件更改的解决方法,因此不会在重新加载时触发复选框:

        If ((Me.CheckBox2.Value <> Sheets(1).Range("t6").Value) And (Me.CheckBox2 = True)) = True Then
    ' do your stuff
    Me.CheckBox2.Value = False
    Else
    Me.CheckBox2.Value = True
    End If
    

    Sheets(1).Range("t6").Value 是存储 checkbox2 值的位置。 我已将此分配给 msgbox 输入,因此当触发 vbno 事件时,将执行其他操作。

    干杯。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-16
      • 1970-01-01
      • 1970-01-01
      • 2019-04-17
      • 1970-01-01
      • 2014-04-07
      相关资源
      最近更新 更多