vb.net 取消 SelectedIndexChanged 并重新选择上一项
vb.net cancel SelectedIndexChanged and reselect previous item
I have a ComboBox
and when a different item is selected some data need to be deleted.
为避免意外删除,我在 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)
这应该可以满足您的大部分需求。它对 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
它只是内化了您可能已经拥有的逻辑,但如果表单上有多个 "cancel-able" 控件,则您不必拥有多个索引跟踪变量。也许这样更简单。
用法:
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
然后在 ComboBox 的 DropDown 事件上,您可以将其设置为等于当前选中的项目。
selected = ComboBox.SelectedItem
然后在您不想更改 SelectedIndexChanged 事件时,您可以简单地将所选项目设置回来。
ComboBox.SelectedItem = selected
可能还有更简洁的方法,但这只是我的想法。
如果您不想存储整个对象而只存储索引,您可以使用 .SelectedIndex 并将变量声明为 Integer。
Now I'm trying to avoid that the event is run twice: when I cancel, the command MyBase.SelectedIndex = MyBase.Items.IndexOf(selectedObject) makes the confirmation is asked twice.
对于那些现在遇到这个问题的人,我添加了一段麻木的代码来阻止它第二次触发。我相信这对多个组合框会很好地工作,但它发生得太快了,如果没有,或者如果你只使用像我这样的组合框,它应该没问题。
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
I have a ComboBox
and when a different item is selected some data need to be deleted.
为避免意外删除,我在 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)
这应该可以满足您的大部分需求。它对 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
它只是内化了您可能已经拥有的逻辑,但如果表单上有多个 "cancel-able" 控件,则您不必拥有多个索引跟踪变量。也许这样更简单。
用法:
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
然后在 ComboBox 的 DropDown 事件上,您可以将其设置为等于当前选中的项目。
selected = ComboBox.SelectedItem
然后在您不想更改 SelectedIndexChanged 事件时,您可以简单地将所选项目设置回来。
ComboBox.SelectedItem = selected
可能还有更简洁的方法,但这只是我的想法。
如果您不想存储整个对象而只存储索引,您可以使用 .SelectedIndex 并将变量声明为 Integer。
Now I'm trying to avoid that the event is run twice: when I cancel, the command MyBase.SelectedIndex = MyBase.Items.IndexOf(selectedObject) makes the confirmation is asked twice.
对于那些现在遇到这个问题的人,我添加了一段麻木的代码来阻止它第二次触发。我相信这对多个组合框会很好地工作,但它发生得太快了,如果没有,或者如果你只使用像我这样的组合框,它应该没问题。
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