Search code examples
c#winformseventscomboboxcustom-controls

How do I prevent the SelectedIndex of a ComboBox from changing?


I am looking for an event where I can prevent the SelecteIndex property of a ComboBox from being set. Maybe also a self created event named "SelectedIndexChanging". I need this to stop the SelectedIndex from changing until a specific condition is true.

I tried looking for an Event where i can prevent the change of SelectedIndex. Also I tried in my CustomComboBox to implement an Event to stop this. No success here.

Thanks in advance.

Edit When the Usere change the ComboBox, i will look if that object is saved in database and when not, if will mask him(With a MessageBox) if he wanted to save. With that DialogResult, i want to interrupt the changing of the SelectedIndex.


Solution

  • This is a little bit of a hack, because the SelectedIndex property value does actually change but is changed back again if the SelectedIndexChanging event is cancelled, but it will certainly appear to work from the user's perspective. You might need to check how things like SelectedValue behave, if you're using them.

    internal class ComboBoxEx : ComboBox
    {
        private int previousSelectedIndex = -1;
        private bool isRevertingSelectedIndex = false;
    
        public event EventHandler<CancelEventArgs> SelectedIndexChanging;
    
        protected virtual void OnSelectedIndexChanging(CancelEventArgs e)
        {
            SelectedIndexChanging?.Invoke(this, e);
        }
    
        protected override void OnSelectedIndexChanged(EventArgs e)
        {
            if (isRevertingSelectedIndex)
            {
                isRevertingSelectedIndex = false;
    
                // Ignore the event altogether.
                return;
            }
    
            var cea = new CancelEventArgs();
    
            OnSelectedIndexChanging(cea);
    
            if (cea.Cancel)
            {
                // Revert the index to its previous value, so it appears not to have changed.
                isRevertingSelectedIndex = true;
                SelectedIndex = previousSelectedIndex;
    
                // Do not process the event any further.
                return;
            }
    
            // Commit the index change.
            previousSelectedIndex = SelectedIndex;
    
            base.OnSelectedIndexChanged(e);
        }
    }
    

    You just handle the SelectedIndexChanging event and set e.Cancel to true if the SelectedIndex shouldn't change.