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 mo
You should handle the ComboBox.SelectedIndexChanged event. Something like:
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.
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 not been modified. (Handling the SelectionChangeCommited event, 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.
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 IndexChanging
event or something in the regular ComboBox
that can be cancelled.
The solution is a combination of @AftabAhmedKalhoro's and @jeffamaphone's posts but using the Tag
property instead.
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 Tag
property, because it is kind of hidden if you're not use to using it (kind of left over from 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 SelectedIndex
will cause the event to fire again in this line:
ComboBox1.SelectedIndex = ComboBox1.Tag
Here is how we can subclass ComboBox to introduce new SelectedIndexChangingEvent with a possibility to cancel the changing:
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;
}
}
}