Остановить выбор элементов в списке при щелчке правой кнопкой мыши

У меня есть ListView в форме Windows в VB 2010.

Я установил свойство MultiSelect объекта ListView на False, чтобы в любой момент можно было выбрать только один элемент.

Я настроил контекстное меню для ListView, и оно правильно отображается при щелчке правой кнопкой мыши ListView.

[Добавлен элемент управления ContextMenuStrip в конструктор и установил для него свойство ContextMenuStrip элемента ListView.]

Рассмотрим два сценария:

  1. Пользователь щелкает правой кнопкой мыши элемент, который уже выбран в ListView. Затем отображается контекстное меню, и проблем нет.

  2. Пользователь щелкает правой кнопкой мыши элемент, отличный от элемента, который уже выбран в ListView. Затем перед отображением контекстного меню выбирается элемент, который пользователь щелкнул правой кнопкой мыши.

В сценарии 2 мне нужно остановить автоматический выбор элемента, который пользователь щелкает правой кнопкой мыши. Необходимо контекстное меню для отображения, но ранее выбранный элемент должен оставаться выбранным.

Как я могу этого добиться?

Я заметил, что в событии ListView MouseDown свойство SelectedItems.Item(0).Index все еще находится в старом индексе. Однако в событии MouseUp это свойство изменяется на новый индекс.

Как я могу остановить изменение SelectedItems в обработчике событий MouseDown или где-нибудь еще? Или как я могу вернуть его к предыдущему выбранному элементу (так, чтобы пользователь не заметил, что он изменяется, а затем возвращается обратно)?

Я могу щелкнуть правой кнопкой мыши MouseDown или MouseUp, используя приведенный ниже код. Однако я не уверен, что мне нужно добавить в это условие, чтобы SelectedItems не изменился.

    If e.Button = Windows.Forms.MouseButtons.Right Then
        ...
    End If

Примечание: я могу использовать для этого следующий код. Однако, когда я использую это со сценарием (2), он выбирает элемент, на котором пользователь щелкнул правой кнопкой мыши, а затем меняет его обратно на предыдущий элемент, и это изменение обратно видно пользователю. Следовательно, это решение нельзя использовать.

Dim intPrevSelectedIndex As Integer = -1
Dim boolCancel As Boolean = False
Private Sub ListView1_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles ListView1.MouseDown
    If ListView1.SelectedItems.Count > 0 AndAlso e.Button = Windows.Forms.MouseButtons.Right Then
            boolCancel = True
            intPrevSelectedIndex = ListView1.SelectedItems(0).Index
        End If
End Sub

Private Sub ListView1_MouseUp(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles ListView1.MouseUp
    If boolCancel Then
        lstWalkResults.Items(intPrevSelectedIndex).Selected = True
        boolCancel = False
    End If
End Sub

Пожалуйста, дайте мне знать о любых возможных решениях. Спасибо за ваше время!


person slayernoah    schedule 21.03.2014    source источник


Ответы (1)


В коде позади вы должны иметь возможность обрабатывать событие щелчка правой кнопкой мыши. В этом методе вы должны отображать контекстное меню вручную, а затем игнорировать событие щелчка, препятствующее выбору элемента.

If e.Button = Windows.Forms.MouseButtons.Right Then
    //display context menu because you're handling the click event manually.
    ...context menu code...
    Dim ee As New System.Windows.Forms.MouseEventArgs(Forms.MouseButtons.None, e.Clicks, e.X, e.Y, e.Delta)
    e = ee
End If
person alan    schedule 21.03.2014
comment
e.Handled = true не работает. Я получаю сообщение об ошибке: 'Handled' is not a member of 'System.Windows.Forms.MouseEventArgs'. - person slayernoah; 21.03.2014
comment
Быстрый поиск в Google на MouseEventArgs дал решение. См. Мой исправленный ответ. - person alan; 21.03.2014
comment
Я пробовал. Dim Hme As HandledMouseEventArgs = e приводит к ошибке: Unable to cast object of type 'System.Windows.Forms.MouseEventArgs' to type 'System.Windows.Forms.HandledMouseEventArgs'. - person slayernoah; 21.03.2014
comment
Обновите свой вопрос, указав, что вы пробовали по моему предложению, и в чем заключалась ошибка. Ответ, который я предоставил, должен сработать, см. Это сообщение MSDN, в котором показано именно то, что я показываю вам в своем ответе: msdn.microsoft.com/en-us/library/ - person alan; 21.03.2014
comment
Класс HandledMouseEventArgs, упомянутый в Ссылка MSDN предназначена для предотвращения отправки события MouseWheel в его родительский контейнер. Это не работает с событием MouseDown. - person slayernoah; 21.03.2014
comment
Хорошо, после некоторого исследования я обнаружил, что вы не можете отметить обработанное событие (в WPF вы можете), но вместо этого вы можете игнорировать событие. См. Мой исправленный ответ. - person alan; 22.03.2014
comment
e.Button = MouseButtons.None тоже не работает. Я получаю сообщение об ошибке Property 'Button' is 'ReadOnly' - person slayernoah; 22.03.2014
comment
Спасибо за обновления. Я пробовал новый код. Он принимает только: System.Windows.Forms.MouseEventArgs( Windows .Forms.MouseButtons.Right, e.Clicks, e.X, e.Y, e.Delta) e = ee, но все же не останавливает срабатывание правого щелчка и выбор элемента в списке. :( - person slayernoah; 26.03.2014
comment
Прошу прощения, в моем ответе была опечатка. См. Измененный ответ. - person alan; 27.03.2014
comment
Я пробовал это без добавления кода контекстного меню. e.Button получает значение None. Однако событие все равно срабатывает. Также появляется контекстное меню. - person slayernoah; 27.03.2014
comment
Это код, который я использовал: ‹br/› Private Sub ListBox1_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown ‹br/› If e.Button = Windows.Forms.MouseButtons.Right Then ‹br/› Dim ee As New System.Windows.Forms.MouseEventArgs(Windows.Forms.MouseButtons.None, e.Clicks, e.X, e.Y, e.Delta) ‹br/› e = ee ‹br/› End If ‹br/› End Sub - person slayernoah; 27.03.2014
comment
@slayernoah Если я не ошибаюсь, это именно тот код, который я предлагал вам использовать. Почему это не было принято в качестве ответа? - person alan; 31.03.2014
comment
Я хотел сказать, что код, который я использовал выше (то, что вы предложили), к сожалению, не работал. - person slayernoah; 31.03.2014
comment
Затем вам необходимо указать полученную ошибку или проблему, с которой вы столкнулись. Также обновите исходный вопрос, указав то, что вы пробовали, и предоставьте код целиком. - person alan; 31.03.2014