.net 如何处理 ComboBox 选定的索引更改?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/782313/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I handle ComboBox selected index changing?
提问by nightcoder
I have a ComboBox that have a list of manufacturers. When a user selects a manufacturer, a grid below is populated with data for the chosen manufacturer. That data can be modified. The user has to press the Save button after all changes are done.
我有一个包含制造商列表的 ComboBox。当用户选择制造商时,下方的网格将填充所选制造商的数据。该数据可以修改。完成所有更改后,用户必须按“保存”按钮。
But the user can forget to press Save and select another manufacturer from the ComboBox and the grid will be populated with another data, so previous changes will be lost.
但是用户可能忘记按 Save 并从 ComboBox 中选择另一个制造商,并且网格将填充另一个数据,因此之前的更改将丢失。
So I need to ask user if he wants to save changes before selecting another manufacturer.
所以我需要在选择其他制造商之前询问用户是否要保存更改。
How can I do this? Or maybe you offer another way of solving my task (looking from another angle)?
我怎样才能做到这一点?或者,也许您提供了另一种解决我的任务的方法(从另一个角度看)?
采纳答案by i_am_jorf
You should handle the ComboBox.SelectedIndexChanged event. Something like:
您应该处理 ComboBox.SelectedIndexChanged 事件。就像是:
this.ComboBox1.SelectedIndexChanged += new system.EventHandler(ComboBox1_SelectedIndexChanged);
Then ComboBox1_SelectedIndexChanged()will be called whenever it changes and you can update your manufacturer info in that function. Save the old info before populating the new info. Or prompt the user if they really want to change it before saving.
然后ComboBox1_SelectedIndexChanged()将在更改时调用,您可以在该函数中更新制造商信息。在填充新信息之前保存旧信息。或者在保存之前提示用户是否真的要更改它。
回答by nightcoder
Here is how we can subclass ComboBox to introduce new SelectedIndexChangingEvent with a possibility to cancel the changing:
以下是我们如何将 ComboBox 子类化以引入新的 SelectedIndexChangingEvent 并有可能取消更改:
public class ComboBoxEx : ComboBox
{
public event CancelEventHandler SelectedIndexChanging;
[Browsable(false)]
public int LastAcceptedSelectedIndex { get; private set; }
public ComboBoxEx()
{
LastAcceptedSelectedIndex = -1;
}
protected void OnSelectedIndexChanging(CancelEventArgs e)
{
var selectedIndexChanging = SelectedIndexChanging;
if (selectedIndexChanging != null)
selectedIndexChanging(this, e);
}
protected override void OnSelectedIndexChanged(EventArgs e)
{
if (LastAcceptedSelectedIndex != SelectedIndex)
{
var cancelEventArgs = new CancelEventArgs();
OnSelectedIndexChanging(cancelEventArgs);
if (!cancelEventArgs.Cancel)
{
LastAcceptedSelectedIndex = SelectedIndex;
base.OnSelectedIndexChanged(e);
}
else
SelectedIndex = LastAcceptedSelectedIndex;
}
}
}
回答by Aftab Ahmed Kalhoro
Create 2 class level variables
创建 2 个类级变量
private bool selectionCancelled=false;
private int lastSelectedIndex=-1;
Then in SelectedIndex event you can write code as following
然后在 SelectedIndex 事件中,您可以编写如下代码
if (!selectionCancelled)
{
if (MessageBox.Show("Are you sure you want to change the selection ?", this.Text, MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.No)
{
selectionCancelled = true;
comboBox.SelectedIndex = lastSelectedIndex;
return;
}
lastSelectedIndex = comboBox.SelectedIndex;
// Normal code of the event handler
}
else
{
selectionCancelled = false;
}
回答by Mark Ainsworth
Night Coder's solution is elegant and concise. I have packaged it in a dll.
(I call it CustomControls.) To do this create a new class library and add the first few statements to Night Coder's solution (copied here as a convenience).
Night Coder 的解决方案优雅简洁。我已经将它打包在一个 dll 中。
(我称之为 CustomControls。)为此,创建一个新的类库并将前几条语句添加到 Night Coder 的解决方案中(为了方便起见,复制到此处)。
Once you have compiled the code, you can add it as a reference. I actually loaded the dll into my Visual Studio Tools pane. That way I can drag the control onto my form at design time. Conveniently, the new event shows up in the properties list.
编译代码后,您可以将其添加为参考。我实际上将 dll 加载到我的 Visual Studio 工具窗格中。这样我就可以在设计时将控件拖到我的表单上。方便的是,新事件显示在属性列表中。
use System.ComponentModel;
use System.Windows.Forms; //this will need to be added as a reference
//your namespace will name your dll call it what you will
namespace CustomControls
Night Coder's solution follows:
Night Coder 的解决方案如下:
public class ComboBoxEx : ComboBox
{
public event CancelEventHandler SelectedIndexChanging;
[Browsable(false)]
public int LastAcceptedSelectedIndex { get; private set; }
public ComboBoxEx()
{
LastAcceptedSelectedIndex = -1;
}
protected void OnSelectedIndexChanging(CancelEventArgs e)
{
var selectedIndexChanging = SelectedIndexChanging;
if (selectedIndexChanging != null)
selectedIndexChanging(this, e);
}
protected override void OnSelectedIndexChanged(EventArgs e)
{
if (LastAcceptedSelectedIndex != SelectedIndex)
{
var cancelEventArgs = new CancelEventArgs();
OnSelectedIndexChanging(cancelEventArgs);
if (!cancelEventArgs.Cancel)
{
LastAcceptedSelectedIndex = SelectedIndex;
base.OnSelectedIndexChanged(e);
}
else
SelectedIndex = LastAcceptedSelectedIndex;
}
}
}
回答by user2905700
An easy way to keep track of unsaved changes.
跟踪未保存更改的简单方法。
After loading any original values, disable the "Save" button.
加载任何原始值后,禁用“保存”按钮。
When the user attempts to leave, check to see if the "Save" button is enabled.
当用户试图离开时,检查是否启用了“保存”按钮。
Enable or disable the "Save" button as required.
根据需要启用或禁用“保存”按钮。
回答by A Guest
I know this is an older question but I thought I'd add the method that I used. I'm not sure if it's any better. There should be a IndexChangingevent or something in the regular ComboBoxthat can be cancelled.
我知道这是一个较旧的问题,但我想我会添加我使用的方法。我不确定它是否更好。应该有一个IndexChanging事件或常规ComboBox中可以取消的东西。
The solution is a combination of @AftabAhmedKalhoro's and @jeffamaphone's posts but using the Tagproperty instead.
解决方案是结合@AftabAhmedKalhoro 和@jeffamaphone 的帖子,但使用该Tag属性。
I didn't want to sub class the ComboBox, or have any extra private variables floating around in the form. But some might not like the Tagproperty, because it is kind of hidden if you're not use to using it (kind of left over from VB6).
我不想子类化ComboBox,或者在表单中浮动任何额外的私有变量。但有些人可能不喜欢这个Tag属性,因为如果你不习惯使用它,它就会被隐藏起来(有点像 VB6 遗留下来的)。
Private Sub MainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ComboBox1.Items.Add("Item1")
ComboBox1.Items.Add("Item2")
ComboBox1.Items.Add("Item3")
ComboBox1.Items.Add("Item4")
' Load Value from database or whatever and set the value or index.
ComboBox1.SelectedIndex = 0
ComboBox1.Tag = ComboBox1.SelectedIndex
' I add the handler at the end because I don't want it to fire during loading the form.
AddHandler ComboBox1.SelectedIndexChanged, New EventHandler(AddressOf ComboBox1_SelectedIndexChanged)
End Sub
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
If (ComboBox1.Tag <> ComboBox1.SelectedIndex) Then
If MessageBox.Show("Warning! You are changing the index." & vbCrLf & _
"Do you wish to continue?", _
"Changing Index", _
MessageBoxButtons.YesNo, _
MessageBoxIcon.Warning) = Windows.Forms.DialogResult.Yes Then
ComboBox1.Tag = ComboBox1.SelectedIndex
' Do Something.
Else
ComboBox1.SelectedIndex = ComboBox1.Tag
End If
End If
End Sub
Note that resetting the SelectedIndexwill cause the event to fire again in this line:
请注意,重置SelectedIndex将导致事件在此行中再次触发:
ComboBox1.SelectedIndex = ComboBox1.Tag
回答by A Guest
Great job nightcoder. Your code Works perfectly.
出色的夜间编码器。您的代码完美运行。
Thanks!
谢谢!
For developers who write in VB.NET here you have translation:
对于用 VB.NET 编写的开发人员,这里有翻译:
Imports System.ComponentModel
Public Class ComboBoxEx
Inherits ComboBox
Private pLastAcceptedSelectedIndex As Integer
Public Event SelectedIndexChanging As CancelEventHandler
Public Property LastAcceptedSelectedIndex() As Integer
Get
Return pLastAcceptedSelectedIndex
End Get
Set(ByVal value As Integer)
pLastAcceptedSelectedIndex = value
End Set
End Property
Public Sub New()
LastAcceptedSelectedIndex = -1
End Sub
Protected Sub OnSelectedIndexChanging(ByVal e As CancelEventArgs)
RaiseEvent SelectedIndexChanging(Me, e)
End Sub
Protected Overrides Sub OnSelectedIndexChanged(ByVal e As System.EventArgs)
If LastAcceptedSelectedIndex <> SelectedIndex Then
Dim cancelEventArgs As CancelEventArgs
cancelEventArgs = New CancelEventArgs()
OnSelectedIndexChanging(cancelEventArgs)
If Not cancelEventArgs.Cancel Then
LastAcceptedSelectedIndex = SelectedIndex
MyBase.OnSelectedIndexChanged(e)
Else
SelectedIndex = LastAcceptedSelectedIndex
End If
End If
End Sub
End Class
回答by Tormod Fjeldsk?r
If you wonder how you can receive notification when the selection changes, you can subscribe to the ComboBox.SelectedIndexChangedevent.
如果您想知道如何在选择更改时收到通知,您可以订阅该ComboBox.SelectedIndexChanged事件。
If you want to offer the user the option to save, only when something has changed and she has forgotten so save her changes, you need to keep track of when these other fields change. This could be accomplished by maintaining a boolean value which is set to true whenever the user edits any fields. When the mentioned event occurs, check this value before deciding whether to offer the option to save.
如果您想为用户提供保存选项,仅当某些内容发生更改而她忘记保存更改时,您需要跟踪这些其他字段何时更改。这可以通过维护一个布尔值来实现,该值在用户编辑任何字段时都设置为 true。当上述事件发生时,在决定是否提供保存选项之前检查此值。
回答by Noldorin
The best thing to do here is compare the data entered in the ComboBox(likewise with other fields) to that already stored (in whatever - the DataSet, list object, etc.) and check for any differences. This way, if the user selects another item from the ComboBox but then changes it back to the original one, the program recognises that the data has still notbeen modified. (Handling the SelectionChangeCommitedevent, for example, and setting a boolean to true, wouldn't allow this to be detected, and would additionally be marginally harder to implement.) In this situation, the simplest and most elegant approach would also seem to provide the best functionality.
最好的做法是将输入的数据ComboBox(与其他字段一样)与已存储的数据(在任何 - DataSet、列表对象等中)进行比较,并检查是否有任何差异。这样一来,如果用户选择从ComboBox另一个项目,但然后更改回原来的一个,该程序可以识别的数据仍然没有被修改。(SelectionChangeCommited例如,处理事件并将布尔值设置为true,将不允许检测到这一点,而且实现起来会稍微困难一些。)在这种情况下,最简单和最优雅的方法似乎也提供了最好的功能。
回答by Jhonny D. Cano -Leftware-
The ComboBox provides an event called SelectedIndexChanged. This event raises whenever the Property SelectedIndex changes, so you have to handle the event for, Whenever the user wants to change the index of the combo, if the user has not saved the changes, Ask him to do so.
ComboBox 提供了一个名为 SelectedIndexChanged 的事件。每当属性 SelectedIndex 更改时都会引发此事件,因此您必须处理该事件,每当用户想要更改组合的索引时,如果用户尚未保存更改,请让他这样做。

