vb.net отменить SelectedIndexChanged и повторно выбрать предыдущий элемент
У меня есть ComboBox
и когда выбран другой элемент, некоторые данные должны быть удалены.
Чтобы избежать случайного удаления, я добавил подтверждающее сообщение на SelectedIndexChanged
событие.
Таким образом, данные отменяются только после подтверждения.
Моя проблема: Как я могу также избежать изменения выбранного элемента, если он не подтвержден?
(Я хочу сохранить предыдущий выбранный индекс)
Я заметил, что я не могу использовать e.cancel
или же e.handled
Я также знаю, что могу хранить фактическое значение в глобальной переменной и использовать его для восстановления предыдущего значения, но я прошу лучшего решения (если это возможно).
РЕДАКТИРОВАТЬ
В то время я храню индекс в переменной уровня формы и использую логическое значение, чтобы избежать выполнения события дважды. Ниже вы можете увидеть мой код:
Private Sub CBox_AmType_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CBox_AmType.SelectedIndexChanged
If DontRunSelChange Then
DontRunSelChange = False
Exit Sub
End If
'...some code
Dim OkCanc As DialogResult = MessageBox.Show("Are you sure?", "Changing confirmation",
MessageBoxButtons.OKCancel, MessageBoxIcon.Question)
If OkCanc = vbCancel Then
DontRunSelChange = True 'This to avoid running twice
CBox_AmType.SelectedIndex = AmType_Index
Exit Sub
End If
'...some code
End sub
РЕДАКТИРОВАТЬ 2
Ниже приведена моя попытка использования кода Plutonix:
Private Sub ComboBoxEx1_SelectedIndexChanging(sender As Object, e As SelectedIndexChangingEventArgs) Handles ComboBoxEx1.SelectedIndexChanging
Dim SN As DialogResult = MessageBox.Show("Are you sure?", "Changing confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
If SN = DialogResult.No Then
e.Cancel = True
Exit Sub
End If
Me.Lbl_Text.Text = Me.ComboBoxEx1.SelectedItem.ToString
End Sub
Но событие запускается дважды, вызывается строкой:
MyBase.SelectedIndex = MyBase.Items.IndexOf(selectedObject)
2 ответа
Это должно делать большую часть того, что вы хотите. Это подклассы ComboBox
добавить новое событие, которое срабатывает до SelectedIndexChanged
событие. Если вы отмените это событие, оно не сработает.
Public Class SelectedIndexChangingEventArgs
Inherits EventArgs
Public Property Cancel As Boolean = False
Public Property NewIndex As Int32 = -1
Friend Sub New(index As Int32)
NewIndex = index
End Sub
End Class
Public Class ComboBoxEx
Inherits ComboBox
Private selectedObject As Object = Nothing
Public Event SelectedIndexChanging(sender As Object,
e As SelectedIndexChangingEventArgs)
Public Sub New()
MyBase.New()
End Sub
Protected Overrides Sub OnSelectedIndexChanged(e As EventArgs)
Dim evArgs As New SelectedIndexChangingEventArgs(MyBase.SelectedIndex)
RaiseEvent SelectedIndexChanging(Me, evArgs)
If evArgs.Cancel Then
If selectedObject IsNot Nothing Then
MyBase.SelectedIndex = MyBase.Items.IndexOf(selectedObject)
Else
MyBase.SelectedIndex = -1
End If
Return ' do not fire Changed event
End If
MyBase.OnSelectedIndexChanged(e)
selectedObject = MyBase.Items(MyBase.SelectedIndex)
End Sub
End Class
Он просто усваивает логику, которую вы, вероятно, уже используете, но если в форме имеется более одного "отменяемого" элемента управления, вам не нужно иметь несколько переменных отслеживания индекса. Может быть, это проще.
Использование:
Private Sub ComboBoxEx1_SelectedIndexChanging(sender As Object,
e As SelectedIndexChangingEventArgs) Handles ComboBoxEx1.SelectedIndexChanging
If ComboBoxEx1.Items(e.NewIndex).ToString.Contains("o") Then
e.Cancel = True
End If
End Sub
Так как Items
Коллекция может быть изменена, простой LastIndex
переменной может не хватить - она может ссылаться на неправильный элемент после того, как что-то добавлено или удалено. Он отслеживает последний выбранный объект и пытается найти его в текущем списке.
Это также работает с DataSource
, но, вероятно, следует учитывать и ряд других ситуаций.
Вы можете сохранить текущий выбранный элемент в глобальной переменной, например
Dim selected As Object
Затем в событии DropDown ComboBox вы можете установить его равным тому, что в данный момент делает выбранный элемент.
selected = ComboBox.SelectedItem
Затем на вашем событии SelectedIndexChanged, когда вы не хотите, чтобы он изменился, вы можете просто вернуть выбранный элемент обратно.
ComboBox.SelectedItem = selected
Есть, вероятно, более чистые способы, но это было просто из головы.
Если вы не хотите хранить весь объект и только индекс, вы можете использовать.SelectedIndex и объявить переменную как Integer.
Теперь я пытаюсь избежать того, чтобы событие запускалось дважды: когда я отменяю, команда MyBase.SelectedIndex = MyBase.Items.IndexOf(selectedObject) запрашивает подтверждение дважды.
Для тех, кто сталкивается с этим сейчас, я добавил ошеломляющий фрагмент кода, который не дает ему сработать во второй раз. Я считаю, что это будет нормально работать с несколькими комбинированными списками, но это происходит так быстро, что все должно быть хорошо, если это не так, или если вы используете только один, как я.
Public Class SelectedIndexChangingEventArgs
Inherits EventArgs
Public Property Cancel As Boolean = False
Public Property NewIndex As Int32 = -1
Friend Sub New(index As Int32)
NewIndex = index
End Sub
End Class
Public Class ComboBoxEx
Inherits ComboBox
Private selectedObject As Object = Nothing
Private Property Numb As Boolean = False
Public Event SelectedIndexChanging(sender As Object,
e As SelectedIndexChangingEventArgs)
Public Sub New()
MyBase.New()
End Sub
Protected Overrides Sub OnSelectedIndexChanged(e As EventArgs)
Dim evArgs As New SelectedIndexChangingEventArgs(MyBase.SelectedIndex)
If Numb = False Then
RaiseEvent SelectedIndexChanging(Me, evArgs)
Else
Numb = False
End If
If evArgs.Cancel Then
If selectedObject IsNot Nothing Then
Numb = True
MyBase.SelectedIndex = MyBase.Items.IndexOf(selectedObject)
Else
MyBase.SelectedIndex = -1
End If
Return ' do not fire Changed event
End If
MyBase.OnSelectedIndexChanged(e)
selectedObject = MyBase.Items(MyBase.SelectedIndex)
End Sub
End Class
На всякий случай кому пригодится:P