Как оценить MultiSelect для MSForms.ListBox VBA? - PullRequest
0 голосов
/ 16 октября 2018

Привет, я хочу добиться следующего:

У меня есть UserForm с ListBox в нем.Этот ListBox должен иметь следующее поведение выбора:

Это мой список:

enter image description here

1 MouseClick Переключение выбора

enter image description here

2 MoveOver над элементом, удерживая нажатой кнопку мыши, переключит выбор

enter image description here

К сожалению, этому поведению не соответствуют 3 выбираемые свойства MultiSelect.

0 - fmMultiSelectSingle

  • Невозможно выбрать несколько элементов

1-fmMultiSelectMulti

Довольно близко, но:

  • ListItems отменяются, когда мышь больше не находится над элементом, удерживая кнопку нажатой.

2-fmMultiSelectExtended

Также довольно близко, но:

  • при нажатии в другом месте, когда элементы выбраны, все элементы будут отменены

Таким образом, цель состоит в том, чтобы вручную переключать все элементы одним нажатиемна них или наведении на них при нажатии мыши

Я пытался сделать это с помощью события ListBox_Change, но не могу понять, как ..

Это код, который я пробовал:

Пользовательская форма в целом:

Private Type TView
    SelectedCol As Collection
    EventsDisabled As Boolean
End Type

Private this As TView

Public Property Get SelectedCol() As Collection
    Set SelectedCol = this.SelectedCol
End Property
Public Property Set SelectedCol(ByVal value As Collection)
    Set this.SelectedCol = value
    'Validate
End Property

Private Sub UserForm_Initialize()
Set SelectedCol = New Collection
counter = 0
Dim i As Integer

For i = 1 To OptionList.ListCount
    SelectedCol.Add Me.OptionList.Selected(i)
Next i
End Sub

SubSecriptSelectedCol:

Sub UpdateSelectedCol()
Dim i As Integer
Dim bo As Boolean
For i = OptionList.ListCount To 1
    SelectedCol.Remove (i)
Next i
For i = 1 To OptionList.ListCount
    SelectedCol.Add OptionList.Selected(i - 1)
Next i

End Sub

Событие ListBox_Change:

Private Sub OptionList_Change()
Dim i As Integer
If this.EventsDisabled = False Then
    this.EventsDisabled = True
    GO_btn.Enabled = ISSelected(Me.OptionList)

    ' keep selected until changed
    For i = 1 To Me.OptionList.ListCount
        If SelectedCol.Item(i) Then
            Me.OptionList.Selected(i) = True
        End If
    Next i

    Debug.Print SelectedCount(Me.OptionList)
    UpdateSelectedCol
End If
this.EventsDisabled = False
End Sub

Итак, я попробовал следующее:Когда выбор будет изменен, он будет сравнивать, был ли этот элемент выбран ранее, и сохранит его.Это не меняет поведение MultiSelect немного.По моему мнению, он должен по крайней мере сохранить все выбранные элементы, которые были выбраны один раз.

РЕДАКТИРОВАТЬ: Добавлены некоторые картинки и код в качестве примера того, что я пытался, и как это должно работать.

1 Ответ

0 голосов
/ 17 октября 2018

Ок, я понял:

Сначала вы начинаете с 1-MultiSelectMulti в качестве свойства ListBox.Затем вы добавляете следующий код в свою пользовательскую форму:

Решение

Private Sub OptionList_Change()
Dim i As Integer
If Not this.EventsDisabled Then
    this.EventsDisabled = True
    GO_btn.Enabled = ISSelected(Me.OptionList)

    ' MAIN SOLUTION ************************************************

    ' if has changed keep odl value when not = to listindex
    For i = 1 To Me.OptionList.ListCount
        If Me.OptionList.Selected(i - 1) <> SelectedCol.Item(i) And Not i - 1 = Me.OptionList.ListIndex Then
            ToggleItem (i)
        End If

    ' MAIN SOLUTION END ************************************************

    UpdateSelectedCol
    this.EventsDisabled = False
End If
End Sub

Отличной подсказкой было свойство .ListIndex, которое сообщает вам, где находится "Курсор" в списке.Это также, где ваша мышь будет находиться при удерживании мыши.Таким образом, все, что нужно сделать, это:

Если значение одного элемента списка изменилось, а индекс индекса не равен индексу измененного элемента, переключите элемент обратно в исходное состояние.

Предварительные требования

Private Type TView
    SelectedCol As Collection
    EventsDisabled As Boolean
End Type

Private this As TView

Public Property Get SelectedCol() As Collection
    Set SelectedCol = this.SelectedCol
End Property
Public Property Set SelectedCol(ByVal value As Collection)
    Set this.SelectedCol = value
    'Validate
End Property

Private Sub UserForm_Initialize()
Set SelectedCol = New Collection
counter = 0
Dim i As Integer

For i = 1 To OptionList.ListCount
    SelectedCol.Add Me.OptionList.Selected(i - 1)
Next i

End Sub


Sub ToggleItem(i As Integer)
    Me.OptionList.Selected(i - 1) = Not Me.OptionList.Selected(i - 1)
End Sub

Sub UpdateSelectedCol()
this.EventsDisabled = True
Dim i As Integer
Dim bo As Boolean
For i = OptionList.ListCount To 1 Step -1
    SelectedCol.Remove (i)
Next i
For i = 1 To OptionList.ListCount
    SelectedCol.Add OptionList.Selected(i - 1)
Next i
this.EventsDisabled = False
End Sub

Для работы необходимы предварительные требования в той же пользовательской форме.UpdateSelectedCol и toggleitem довольно легко восстановить, я думаю.

...