I have a ComboBox
and when a different item is selected some data need to be deleted.
To avoid accidentally deleting, I've added a confirm message on SelectedIndexChanged
event.
This way, data are cancelled only after confirmation.
My problem is: How can I also avoid changing of selected item when not confirmed?
(I wish to mantain the previous selected index)
I noticed that I can't use e.cancel
or e.handled
I also know that I could store actual value in a global variable and use it to restore previous value but I'm asking for a better solution (if it's possible).
EDIT
At the time, I'm storing the Index in a form level variable and I'm using a boolean to avoid executing the event twice. Below you can see my code:
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
EDIT 2
The following is my attempt using Plutonix code:
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
But the event is fired twice, called by the row:
MyBase.SelectedIndex = MyBase.Items.IndexOf(selectedObject)
This should do most of what you want. It subclasses ComboBox
to add a new event which fires before the SelectedIndexChanged
event. If you cancel, then that event does not fire.
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
It just internalizes the logic you probably already have, but if there are more than one "cancel-able" controls on the form, you wont have to have multiple index tracking variables. Maybe that is simpler.
Usage:
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
Since the Items
collection can be modified, a simple LastIndex
variable may not be enough - it could refer to the wrong item after something is added or removed. This tracks the last object selected and tries to find it in the current list.
It also works with a DataSource
, but there are probably a number of other situations to be accounted for.