Is there an easy method to prompt the user to confirm a combo box selection change and not process the change if the user selected no?
We have a combo box where changing the selection will cause loss of data. Basically the user selects a type, then they are able to enter attributes of that type. If they change the type we clear all of the attributes as they may no longer apply. The problem is that to under the selection you raise the SelectionChanged
event again.
Here is a snippet:
if (e.RemovedItems.Count > 0)
{
result = MessageBox.Show("Do you wish to continue?",
"Warning", MessageBoxButton.YesNo, MessageBoxImage.Warning);
if (result == MessageBoxResult.No)
{
if (e.RemovedItems.Count > 0)
((ComboBox)sender).SelectedItem = e.RemovedItems[0];
else
((ComboBox)sender).SelectedItem = null;
}
}
I have two solutions, neither of which I like.
After the user selects 'No', remove the
SelectionChanged
event handler, change the selected item and then register theSelectionChanged
event handler again. This means you have to hold onto a reference of the event handler in the class so that you can add and remove it.Create a
ProcessSelectionChanged
boolean as part of the class. Always check it at the start of the event handler. Set it to false before we change the selection back and then reset it to true afterwards. This will work, but I don't like using flags to basically nullify an event handler.
Anyone have an alternative solution or an improvement on the ones I mention?
In WPF dynamically set the object with
I found this good implementation.
source: http://www.amazedsaint.com/2008/06/wpf-combo-box-cancelling-selection.html
I remember needing to do this a while back. It took me about a week of research and attempts before I found a good solution. I posted it here:
WPF: Cancel a user selection in a databound ListBox?
FYI, it's an M-V-VM based solution (if you aren't using the M-V-VM pattern, you should be!)
Maybe create a class deriving from
ComboBox
, and override theOnSelectedItemChanged
(OrOnSelectionChangeCommitted
.)Validating within the
SelectionChanged
event handler allows you to cancel your logic if the selection is invalid, but I don't know of an easy way to cancel the event or item selection.My solution was to sub-class the WPF combo-box and add an internal handler for the
SelectionChanged
event. Whenever the event fires, my private internal handler raises a customSelectionChanging
event instead.If the
Cancel
property is set on the correspondingSelectionChangingEventArgs
, the event isn't raised and theSelectedIndex
is reverted to its previous value. Otherwise a newSelectionChanged
is raised that shadows the base event. Hopefully this helps!EventArgs and handler delegate for SelectionChanging event:
ChangingComboBox class implementation:
I do not believe using the dispatcher to post (or delay) a property update is a good solution, it is more of a workaround that is not really needed. The following solution i fully mvvm and it does not require a dispatcher.
In the view code behind hook to the SelectionChanged event and update the Source (i.e., the VM) or the Target (i.e. the V) in accordance to whether the VM.ConfirmChange(...) method returned value as follows: