locked
how-to "cancel" changing of current item in ListBox? RRS feed

  • Question

  • I need something like SelectedItemChanging event with Cancel event's argument.
    Tried to use CurrentChanging event for corresponding default CollectionView
    but failed, because cancelling CurrentChanging event doesn't "stop"
    changing of current item in ListBox.

    Friday, March 23, 2007 12:11 AM

Answers

  • You can use ListBox’s SelectionChanged event. Try this:

    Create two bool fields in your code, such as:

                    private bool canceled;  //Selection changing canceled or not.

                    private bool saved;     //Saved or not.

    Now in your selection changed event, use this:

                            //If not saved and selecion changing not canceled and it's not the first time a user selects, let's "cancel" the changing by change the selected value back.If it a first time selection, the RemovedItems.Count will be 0.

                            if (!saved && !canceled && e.RemovedItems.Count != 0)

                            {

                                    //Be sure to add this line, or you'll enter a dead loop.

                                    canceled = true;

                                    //The following line will fire another SelectionChanged event.

                                    listPatient.SelectedItem = e.RemovedItems[0];

                            }

                            //Not saved and not first time selection, but you've already "canceled" the changing.

                            else if (canceled)

                            {

                                    canceled = false;

                            }

                            //Saved or first time selection.

                            else

                            {

                                    saved = false;

                                    //Your logic to change a patient.

                            }

    Finally, in your save button’s click event handler, simply set saved to true.

    Maybe this logic is a little too complicated. But it works. Sorry I don’t have time to work out a better solution.

    Monday, March 26, 2007 6:58 AM

All replies

  • Not sure if I understand your question correctly. Perhaps, setting the IsSynchronizedWithCurrentItem property of the list box to false will suffice.
    Friday, March 23, 2007 5:04 AM
  • I have ListBox data bound to list of objects, a few TextBoxes for editing properties of current object and Save button for applying changes made in current object.

    When user has changed some properties of current object (for example LastName or FirstName of Patient) but didn't press Save Button and tries to select another Patient in ListBox I want to ask the user if he would like to save changes, made to the current data (standard dialog: Save changes? Yes, No, Cancel).

    The question is:

    in which event of wich object can I prevent ListBox of changing currently selected item if user gives Cancel answer?

     

    I have the question because:

     

    I tried to use CurrentChanging event of default collection view:

    // Window Load handler

     

     

    CollectionView patientsCollectionView;

    void OnLoaded(object sender, RoutedEventArgs e)

    {

    ObjectDataProvider provider = (ObjectDataProvider)FindResource("patientsProvider");

    patientsCollectionView = (CollectionView)CollectionViewSource.GetDefaultView(provider.Data);

    patientsCollectionView.CurrentChanging += new System.ComponentModel.CurrentChangingEventHandler(collectionView_CurrentChanging);

    }

     

    void collectionView_CurrentChanging(object sender, System.ComponentModel.CurrentChangingEventArgs e)

    {

    e.Cancel = ! CanLeaveEntity();

    }

     

    List box is declared like here:

    <ListBox Name="patientsListBox"

    IsSynchronizedWithCurrentItem="True"

    ItemsSource="{Binding}"

    DataContext="{StaticResource patientsProvider}"

    />

    The problem is that ListBox CHANGES (!!!!!) currently selected item in case of e.cancel = true in collectionView_CurrentChanging.

    Is it a BUG inWPF?

     

    By the way I tried also:

    void collectionView_CurrentChanging(object sender, System.ComponentModel.CurrentChangingEventArgs e)

    {

    e.Cancel = ! CanLeaveEntity();

    if(e.Cancel == true)

    {

    ListBox l = (ListBox)FindResource("patientsListBox");

    l.SelectedValue = patientsCollectionView.CurrentItem;
    }

    }

     

    But I SEE (!!!) that currently selected item in ListBox changes and then changes back :)))

     

    Regards,

    Sergey.

     

     

    Friday, March 23, 2007 7:08 AM
  • *
    Friday, March 23, 2007 9:24 PM
  • This may not be exactly what you want, but it might inspire you with the exact solution you need:

    http://www.wiredprairie.us/journal/2007/03/extended_mode_listbox_selectio.html

    Essentially, overriding the behavior of the ListBoxItem to not select when you want it (to not select). It doesn't handle DoubleClick (which can be fixed, it's just not in the code on that web page).

    I'm sure there are other solutions, but this one was handy.

    Saturday, March 24, 2007 12:39 AM
  • You can use ListBox’s SelectionChanged event. Try this:

    Create two bool fields in your code, such as:

                    private bool canceled;  //Selection changing canceled or not.

                    private bool saved;     //Saved or not.

    Now in your selection changed event, use this:

                            //If not saved and selecion changing not canceled and it's not the first time a user selects, let's "cancel" the changing by change the selected value back.If it a first time selection, the RemovedItems.Count will be 0.

                            if (!saved && !canceled && e.RemovedItems.Count != 0)

                            {

                                    //Be sure to add this line, or you'll enter a dead loop.

                                    canceled = true;

                                    //The following line will fire another SelectionChanged event.

                                    listPatient.SelectedItem = e.RemovedItems[0];

                            }

                            //Not saved and not first time selection, but you've already "canceled" the changing.

                            else if (canceled)

                            {

                                    canceled = false;

                            }

                            //Saved or first time selection.

                            else

                            {

                                    saved = false;

                                    //Your logic to change a patient.

                            }

    Finally, in your save button’s click event handler, simply set saved to true.

    Maybe this logic is a little too complicated. But it works. Sorry I don’t have time to work out a better solution.

    Monday, March 26, 2007 6:58 AM
  • Three years later! I have the same problem with the DataGrid in WPF 4, VS 2010. Annoying nuisance. Really silly.
    Tuesday, June 15, 2010 8:50 AM
  • This bug with Selector.IsSynchronizedWithCurrentItem is still not fixed in WPF 4.0. However I have worked up a simple attached property to resolve the issue in a clean and MVVM-compliant manner:

    http://coderelief.net/2011/11/07/fixing-issynchronizedwithcurrentitem-and-icollectionview-cancel-bug-with-an-attached-property/


    • Edited by Tim Valentine Wednesday, November 9, 2011 9:49 PM
    • Proposed as answer by Tim Valentine Wednesday, November 9, 2011 9:50 PM
    Wednesday, November 9, 2011 9:49 PM