【问题标题】:VB.net, Referencing changes made to public variables in a private sub within a different private subsVB.net,引用对不同私有子中的私有子中的公共变量所做的更改
【发布时间】:2019-06-22 14:32:57
【问题描述】:

在我的程序(openFile_Click)的一个私有子程序中,我更改了我在公共类中调暗的变量,称为名称、距离和点。但是当我尝试从另一个私人子(btnGameEnter)重新打印它们时,它们是空白的。我知道变量在 openFile sub 测试后已正确设置,并且不知道为什么在 openFile sub 中完成的相同过程(将变量添加到列表框)在 btnGameEnter sub 中不起作用,其中变量应该已经有来自 openFile 的数据。

Public Class frmdetails


    Dim Names(100) As String
    Dim Distance(100, 2) As String
    Dim Points(100, 2) As String

    Private Sub openFile_Click(sender As Object, e As EventArgs) Handles openFile.Click
        OpenFileDialog.ShowDialog()
        Dim strFileName = OpenFileDialog.FileName
        Dim objReader As New System.IO.StreamReader(strFileName)
        Dim textline As String


        lstNames.Items.Clear()
        lstDistance.Items.Clear()
        lstPoints.Items.Clear()

        Dim Count As Integer = 0


        Do While objReader.Peek() <> -1

            textline = objReader.ReadLine() & vbNewLine

            Dim parts() As String = textline.Split("|")

            Names(Count) = parts(0)
            Distance(Count, 0) = parts(1)
            Distance(Count, 1) = parts(2)
            Distance(Count, 2) = parts(3)
            Points(Count, 0) = parts(4)
            Points(Count, 1) = parts(5)
            Points(Count, 2) = parts(6)

            Count = Count + 1


        Loop

        For n = 0 To Count - 1
            lstNames.Items.Add(Names(n))
            lstNames.Items.Add(" ")
            lstDistance.Items.Add(Distance(n, 0) + " Miles")
            lstDistance.Items.Add(" ")
            lstPoints.Items.Add(Points(n, 0))
            lstPoints.Items.Add(" ")
        Next

    End Sub

    Private Sub btnGameEnter_Click(sender As Object, e As EventArgs) Handles btnGameEnter.Click

        Dim ChosenGame As Integer = 0
        Dim Count As Integer = 0

        ChosenGame = cboWhichGame.Text

        lstGameNum.Items.Clear()

        lstNames.Items.Clear()
        lstDistance.Items.Clear()
        lstPoints.Items.Clear()

        lstGameNum.Items.Add(ChosenGame)


        For n = 0 To Count - 1
            lstNames.Items.Add(Names(n))
            lstNames.Items.Add(" ")
            lstDistance.Items.Add(Distance(n, (ChosenGame - 1)) + " Miles")
            lstDistance.Items.Add(" ")
            lstPoints.Items.Add(Points(n, (ChosenGame - 1)))
            lstPoints.Items.Add(" ")
        Next

    End Sub
End Class

【问题讨论】:

  • 这是一个非常标准的错误,您有不止一次 frmdetails 类的实例。您正在查看的一个和一个创建不正确且不可见的一个。添加Public Sub New 并在其上设置断点。第二次命中时,您会在调试器的 Stack Trace 窗口中找到该错误。

标签: arrays vb.net multidimensional-array text-files streamreader


【解决方案1】:

我发现了这些问题:

  1. BtnGameEnter_Click 中,您将一个局部变量初始化为Dim Count As Integer = 0。它的价值永远不会改变。这意味着 for 循环永远不会执行。让它成为一个类字段,而不是在所有 Subs 之间共享它(并从两个 subs 中删除 Dim Count)。

    Public Class frmReferencingFields
        Dim Count As Integer = 0
        ....
    
  2. 您应该使用cboWhichGame.SelectedIndex 初始化ChosenGame,即Integer,其中第一个游戏将是0。所以加的时候不要减1。这使您可以在 ComboBox 中添加口语名称,而不是裸数字。

    Dim ChosenGame As Integer = cboWhichGame.SelectedIndex
    ...
    lstDistance.Items.Add(Distance(n, ChosenGame) + " Miles")
    lstPoints.Items.Add(Points(n, ChosenGame))
    

另外,我不确定您是否为距离和点选择了正确的类型。它们真的是字符串吗?


我提出了另一种方法。名称、距离和点是否代表位置?它假设它。所以让我们创建一个Location

Public Class Location
    Property Name As String
    Property Distance As Double
    Property Points As Integer
End Class

您似乎有 3 场比赛。所以让我们在表单中创建一个像这样的游戏数组

Dim game(2) As List(Of Location)

游戏数量是固定的,因为它取决于文件格式。每个游戏包含可变数量的位置。最好为此使用List(Of T),因为它会自动增长以适应内容。

另外,让我们添加一个方便的例程,将游戏添加到列表中。我们可以在两个 Subs 中重用它。

Private Sub DisplayGame(game As List(Of Location))
    lstNames.Items.Clear()
    lstDistance.Items.Clear()
    lstPoints.Items.Clear()
    For Each location As Location In game
        lstNames.Items.Add(location.Name)
        lstNames.Items.Add(" ")
        lstDistance.Items.Add(location.Distance & " Miles")
        lstDistance.Items.Add(" ")
        lstPoints.Items.Add(location.Points.ToString())
        lstPoints.Items.Add(" ")
    Next
End Sub

请注意,我们如何可以用单个变量 game As List(Of Location) 和位置为 location As Location 来表示游戏,而不必处理单独的名称、距离和点数组。此外,不需要单独的 Count 变量,因为列表会自动跟踪计数。

现在,两个 Subs 变成了

Private Sub OpenFile_Click(sender As Object, e As EventArgs) Handles openFile.Click
    OpenFileDialog.ShowDialog()
    Dim strFileName = OpenFileDialog.FileName

    'Create the lists
    For i As Integer = 0 To UBound(game)
        game(i) = New List(Of Location)()
    Next i

    For Each textline As String In File.ReadLines(strFileName)
        Dim parts() As String = textline.Split("|"c)

        If parts.Length = 7 Then 'Not an empty line
            For g As Integer = 0 To UBound(game)
                Dim location = New Location()
                location.Name = parts(0)
                location.Distance = CDbl(parts(1 + g))
                location.Points = CInt(parts(4 + g))
                game(g).Add(location)
            Next g
        End If
    Next

    DisplayGame(game(0))
End Sub

Private Sub BtnGameEnter_Click(sender As Object, e As EventArgs) Handles btnGameEnter.Click
    Dim ChosenGame As Integer = cboWhichGame.SelectedIndex

    lstGameNum.Items.Clear()
    lstGameNum.Items.Add(ChosenGame)
    DisplayGame(game(ChosenGame))
End Sub

【讨论】:

  • 哇,非常感谢,这真的很深入,很有帮助,我能够理解它。我没想到会有如此坚定的回应。再次感谢您。
猜你喜欢
  • 1970-01-01
  • 2021-07-16
  • 2013-06-11
  • 2011-12-03
  • 2011-05-25
  • 2012-01-25
  • 1970-01-01
  • 2017-10-31
  • 2022-09-24
相关资源
最近更新 更多