用户窗体初始化后更新用户窗体列表框

Update a userform listbox after userform initialization

有什么方法可以在 Userform_Initialize 子之外的 UserForm 上更新 ListBox 吗?

为什么? 我正在构建一个二十一点游戏并使用列表框告诉用户他们有什么牌/庄家有什么牌。我希望使用一个简单的子 (ShowCards) 将项目添加到列表框,但我 运行 遇到了问题:

Play 按钮调用位于普通模块中的 PlayBlackjack sub

Option Explicit

Dim cards As New Collection

Sub ShowGame()
    UFDisplay.Show
End Sub

Sub PlayBlackjack()
    'fill the cards collection with 5 shuffled decks
    PrepareCards

    Dim i As Integer
    Dim userHand As New Collection
    Dim dealerHand As New Collection

    'deal cards (removing the dealt cards from the cards collection)
    For i = 1 To 2
        DealCard cards, userHand
        DealCard cards, dealerHand
    Next i

    ShowCards userHand, UFDisplay.UserHandList <-- ERROR HERE (Type mismatch)

    'more code to follow
End Sub

Private Sub ShowCards(hand As Collection, list As ListBox)
    Dim i As Integer

    For i = 1 To hand.Count
        list.AddItem hand(i).CardName
    Next i
End Sub

如果您认为需要更多代码,请告诉我。 hand 是卡片 类 的集合,其中 .CardName returns 类似于 3 of Hearts

我读到的所有内容似乎都告诉我用户窗体在初始化后是静态的,因此我需要在添加新项目后以某种方式刷新它。我尝试 Userform.Repaint 但没有成功。

所以如果真的没有别的办法,我是否应该将userHanddealerHand声明为全局变量,更新它们并调用Useform_Initialize获取更新后的值并将它们显示给用户?鉴于游戏的性质是可以为两个玩家发更多的牌,因此在每场游戏中多次重新初始化用户表单似乎并不明智。

欢迎所有建议。如果您认为我应该完全不同地做,我仍然很想听听(但对工作表解决方案不太感兴趣)

更新#1 为清楚起见,ShowGame 由工作表上的按钮调用,然后 PlayBlackjack 由用户窗体上的播放按钮调用(用户窗体代码中没有其他内容)

您也可以使用 class 作为手形,并将 class 列表框设置为表单列表框,例如 class clsHand

Public colHand As collection
Public lstToUpdate As MSForms.ListBox

Private Sub Class_Initialize()
    Set colHand = New collection
End Sub

Friend Function AddCard(card As clsCard)
    colHand.Add card, CStr(colHand.Count)
    If Not lstToUpdate Is Nothing Then
        lstToUpdate.AddItem card.strCardName
    End If
End Function

以表格形式使用

Private clsPlayerHand As clsHand

Private Sub UserForm_Initialize()
    Set clsPlayerHand = New clsHand
    Set clsPlayerHand.lstToUpdate = Me.ListBox1
End Sub

Private Sub CommandButton1_Click()
    Dim clsC As New clsCard
    clsC.strCardName = "one"
    clsPlayerHand.AddCard clsC
End Sub

编辑:推荐,

为你的卡片使用数字和花色名称,然后你可以执行以下操作,比如启用拆分按钮,顺便说一下,你会使用手牌数组然后 arrHands(x) ...

Public colHand As collection
Public lstToUpdate As MSForms.ListBox
Public cmdSplitButton As MSForms.CommandButton

Private Sub Class_Initialize()
    Set colHand = New collection
End Sub

Friend Function AddCard(card As clsCard)
    colHand.Add card, CStr(colHand.Count)
    If Not lstToUpdate Is Nothing Then
        lstToUpdate.AddItem card.CardName
    End If
    If Not cmdSplitButton Is Nothing Then
        If colHand.Count = 2 Then _
        cmdSplitButton.Enabled = colHand(1).NumericPart = colHand(2).NumericPart
    End If
End Function

着眼于使用 classes 以充分发挥其潜力,并着眼于事件,以对某些事情做出反应。

啊,我明白了。您不能将 listBox 参数声明为 ListBox。后者是为 Activex 控件保留的,而不是 VBA 控件。将您的 ShowCardssub 的签名更改为:

Private Sub ShowCards(hand As Collection, list As Control) '<~~ or MSForms.ListBox, or simply as Object...