【问题标题】:How to prevent a second textchanged event from occurring in Visual Basic如何防止在 Visual Basic 中发生第二个 textchanged 事件
【发布时间】:2013-11-24 21:48:51
【问题描述】:

我正在 Visual Studio 2012 中编写一个 Visual Basic 程序,但我遇到了一个我无法自行解决的问题。我正在使用两个带有两个组合框的文本框。应用程序中没有按钮。当您输入数字时,我正在使用 textchanged 事件来触发计算。它将使用一个文本框工作,但是当它在另一个文本框中显示答案时,它会触发文本框 textchanged 事件。因此,没有给我正确的答案。 顺便说一句,这是一个单位转换器,可以将长度转换为米到毫米,米到英尺,米到英寸等......

Public Class frmMain
' class-scope variables
Dim decUnit1 As Decimal
Dim decUnit2 As Decimal
Dim intFlag As Integer

Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles Me.Load
    PopCombo()
    cboUnitType.SelectedIndex = 0
End Sub

Private Sub PopCombo()
    ' populates the comboBoxes and sets default selection

    ' populate the comboBox accordingly
    If cboUnitType.SelectedIndex = 0 Then

        ClearBox()

        With Me.cbo1.Items
            .Add("Meter")
            .Add("Milimeter")
            .Add("Foot")
            .Add("Inch")
        End With

        With Me.cbo2.Items
            .Add("Meter")
            .Add("Milimeter")
            .Add("Foot")
            .Add("Inch")
        End With

        ' set default ComboBox index selection
        cbo1.SelectedIndex = 1
        cbo2.SelectedIndex = 3

    ElseIf cboUnitType.SelectedIndex = 1 Then

        ClearBox()

        With Me.cbo1.Items
            .Add("Celsius")
            .Add("Fahrenheit")
        End With

        With Me.cbo2.Items
            .Add("Celsius")
            .Add("Fahrenheit")
        End With

        cbo1.SelectedIndex = 0
        cbo2.SelectedIndex = 1

    End If

End Sub

Private Sub ClearBox()
    ' clears the comboBox
    cbo1.Items.Clear()
    cbo2.Items.Clear()
End Sub

Private Sub cboUnitType_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboUnitType.SelectedIndexChanged
    PopCombo()
End Sub

Private Sub txtUnit1_TextChanged(sender As Object, e As EventArgs) Handles txtUnit1.TextChanged

    Decimal.TryParse(txtUnit1.Text, decUnit1)
    Decimal.TryParse(txtUnit2.Text, decUnit2)

    If cboUnitType.SelectedIndex = 0 Then
        ' converts meter to...
        If cbo1.SelectedIndex = 0 AndAlso cbo2.SelectedIndex = 0 Then
            ' meter
            txtUnit2.Text = txtUnit1.Text
        ElseIf cbo1.SelectedIndex = 0 AndAlso cbo2.SelectedIndex = 1 Then
            ' millimeter
            txtUnit2.Text = (decUnit1 * 1000).ToString
        ElseIf cbo1.SelectedIndex = 0 AndAlso cbo2.SelectedIndex = 2 Then
            ' foot
            txtUnit2.Text = (decUnit1 * 3.28084).ToString
        ElseIf cbo1.SelectedIndex = 0 AndAlso cbo2.SelectedIndex = 3 Then
            ' inch
            txtUnit2.Text = (decUnit1 * 39.3701).ToString
        End If

        ' converts millimeter to...
        If cbo1.SelectedIndex = 1 AndAlso cbo2.SelectedIndex = 0 Then
            ' meter
            txtUnit2.Text = (decUnit1 * 0.001).ToString
        ElseIf cbo1.SelectedIndex = 1 AndAlso cbo2.SelectedIndex = 1 Then
            ' millimeter
            txtUnit2.Text = txtUnit1.Text
        ElseIf cbo1.SelectedIndex = 1 AndAlso cbo2.SelectedIndex = 2 Then
            ' foot
            txtUnit2.Text = (decUnit1 * 0.00328084).ToString
        ElseIf cbo1.SelectedIndex = 1 AndAlso cbo2.SelectedIndex = 3 Then
            ' inch
            txtUnit2.Text = (decUnit1 * 0.0393701).ToString
        End If

        ' converts foot to...
        If cbo1.SelectedIndex = 2 AndAlso cbo2.SelectedIndex = 0 Then
            ' meter
            txtUnit2.Text = (decUnit1 * 0.3048).ToString
        ElseIf cbo1.SelectedIndex = 2 AndAlso cbo2.SelectedIndex = 1 Then
            ' millimeter
            txtUnit2.Text = (decUnit1 * 304.8).ToString
        ElseIf cbo1.SelectedIndex = 2 AndAlso cbo2.SelectedIndex = 2 Then
            ' foot
            txtUnit2.Text = txtUnit1.Text
        ElseIf cbo1.SelectedIndex = 2 AndAlso cbo2.SelectedIndex = 3 Then
            ' inch
            txtUnit2.Text = (decUnit1 * 12).ToString
        End If

        ' converts inch to...
        If cbo1.SelectedIndex = 3 AndAlso cbo2.SelectedIndex = 0 Then
            ' meter
            txtUnit2.Text = (decUnit1 * 0.0254).ToString
        ElseIf cbo1.SelectedIndex = 3 AndAlso cbo2.SelectedIndex = 1 Then
            ' millimeter
            txtUnit2.Text = (decUnit1 * 25.4).ToString
        ElseIf cbo1.SelectedIndex = 3 AndAlso cbo2.SelectedIndex = 2 Then
            ' foot
            txtUnit2.Text = (decUnit1 * 0.0833333).ToString
        ElseIf cbo1.SelectedIndex = 3 AndAlso cbo2.SelectedIndex = 3 Then
            ' inch
            txtUnit2.Text = txtUnit1.Text
        End If
    End If

End Sub

Private Sub txtUnit2_TextChanged(sender As Object, e As EventArgs) Handles txtUnit2.TextChanged

    Decimal.TryParse(txtUnit1.Text, decUnit1)
    Decimal.TryParse(txtUnit2.Text, decUnit2)

    If cboUnitType.SelectedIndex = 0 Then
        ' converts meter to...
        If cbo1.SelectedIndex = 0 AndAlso cbo2.SelectedIndex = 0 Then
            ' meter
            txtUnit1.Text = txtUnit2.Text
        ElseIf cbo1.SelectedIndex = 1 AndAlso cbo2.SelectedIndex = 0 Then
            ' millimeter
            txtUnit1.Text = (decUnit2 * 1000).ToString
        ElseIf cbo1.SelectedIndex = 2 AndAlso cbo2.SelectedIndex = 0 Then
            ' foot
            txtUnit1.Text = (decUnit2 * 3.28084).ToString
        ElseIf cbo1.SelectedIndex = 3 AndAlso cbo2.SelectedIndex = 0 Then
            ' inch
            txtUnit1.Text = (decUnit2 * 39.3701).ToString
        End If

        ' converts millimeter to...
        If cbo1.SelectedIndex = 0 AndAlso cbo2.SelectedIndex = 1 Then
            ' meter
            txtUnit1.Text = (decUnit2 * 0.001).ToString
        ElseIf cbo1.SelectedIndex = 1 AndAlso cbo2.SelectedIndex = 1 Then
            ' millimeter
            txtUnit1.Text = txtUnit2.Text
        ElseIf cbo1.SelectedIndex = 2 AndAlso cbo2.SelectedIndex = 1 Then
            ' foot
            txtUnit1.Text = (decUnit2 * 0.00328084).ToString
        ElseIf cbo1.SelectedIndex = 3 AndAlso cbo2.SelectedIndex = 1 Then
            ' inch
            txtUnit1.Text = (decUnit2 * 0.0393701).ToString
        End If

        ' converts foot to...
        If cbo1.SelectedIndex = 0 AndAlso cbo2.SelectedIndex = 2 Then
            ' meter
            txtUnit1.Text = (decUnit2 * 0.3048).ToString
        ElseIf cbo1.SelectedIndex = 1 AndAlso cbo2.SelectedIndex = 2 Then
            ' millimeter
            txtUnit1.Text = (decUnit2 * 304.8).ToString
        ElseIf cbo1.SelectedIndex = 2 AndAlso cbo2.SelectedIndex = 2 Then
            ' foot
            txtUnit1.Text = txtUnit2.Text
        ElseIf cbo1.SelectedIndex = 3 AndAlso cbo2.SelectedIndex = 2 Then
            ' inch
            txtUnit1.Text = (decUnit2 * 12).ToString
        End If

        ' converts inch to...
        If cbo1.SelectedIndex = 0 AndAlso cbo2.SelectedIndex = 3 Then
            ' meter
            txtUnit1.Text = (decUnit2 * 0.0254).ToString
        ElseIf cbo1.SelectedIndex = 1 AndAlso cbo2.SelectedIndex = 3 Then
            ' millimeter
            txtUnit1.Text = (decUnit2 * 25.4).ToString
        ElseIf cbo1.SelectedIndex = 2 AndAlso cbo2.SelectedIndex = 3 Then
            ' foot
            txtUnit1.Text = (decUnit2 * 0.0833333).ToString
        ElseIf cbo1.SelectedIndex = 3 AndAlso cbo2.SelectedIndex = 3 Then
            ' inch
            txtUnit1.Text = txtUnit1.Text
        End If
    End If

End Sub

End Class

【问题讨论】:

  • 将事件代码放入被调用的函数中,也许将文本框值作为参数传递并返回一个值(答案),然后当您发布答案时,设置一个忽略标志,以便您不响应你自己的变化。当标志为真时,不要调用新的 procs。 (基本上需要将计算与事件隔离开来,这样你就可以打破循环)。只添加一个 Calc 按钮可能会更容易。
  • 你能给我一些这个忽略标志的示例代码吗?提前致谢。
  • 你这里有递归事件,txtUnit1事件处理程序修改txtUnit2。这将触发 txtUnit2 再次修改 txtUnit1 的事件。这通常是导致程序崩溃的致命事故,但实际上它应该在这里工作。由于转换回应该产生与文本框中已经存在的完全相同的文本,因此不应触发事件。使用调试器找出文本不匹配的原因。顺便说一句,相当不错的调试学习练习,这个作业的重点大概是:)
  • 您似乎可以输入 TB1 以在 TB2 中获得答案,反之亦然。将范例更改为From Tb1 = > To Tb2,以便没有人输入TB2(而不是TB1 <=> TB2)。消除整个问题。使用组合来更改转换单位。

标签: vb.net visual-studio-2012


【解决方案1】:

在更新文本框的 Text 属性时,您需要使用一个或两个布尔变量来抑制文本更改事件。这是一个将 F 度转换为 C 并返回的示例,并允许您在任一文本框中输入值:

Public Class Form4

    Dim suppressTextBox1TextChanged As Boolean = False
    Dim suppressTextBox2TextChanged As Boolean = False

    Private Sub txtDegreesF_TextChanged(sender As System.Object, e As System.EventArgs) Handles txtDegreesF.TextChanged
        'Convert to Celsius

        'Only do the calculation if we are typing the textbox
        If Not suppressTextBox1TextChanged Then
            Dim degreesF As Double
            Dim degreesC As Double
            If Double.TryParse(txtDegreesF.Text, degreesF) Then
                degreesC = (degreesF - 32) * (5 / 9)
                suppressTextBox2TextChanged = True
                txtDegreesC.Text = degreesC.ToString()
                suppressTextBox2TextChanged = False
            End If
        End If

    End Sub

    Private Sub txtDegreesC_TextChanged(sender As System.Object, e As System.EventArgs) Handles txtDegreesC.TextChanged
        'Convert to Fahrenheit

        'Only do the calculation if we are typing the textbox
        If Not suppressTextBox2TextChanged Then
            Dim degreesF As Double
            Dim degreesC As Double
            If Double.TryParse(txtDegreesC.Text, degreesC) Then
                degreesF = (degreesC * 1.8) + 32
                suppressTextBox1TextChanged = True
                txtDegreesF.Text = degreesF.ToString()
                suppressTextBox1TextChanged = False
            End If
        End If
    End Sub
End Class

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-08
    • 1970-01-01
    相关资源
    最近更新 更多