2

Ok, my program in a nutshell has a list of customers. Those customers are all listed in a listbox so when one is clicked on all of their information appears on the form. This works through databinding, all of the controls on the page are bound to the listbox's selectedItem.

What I would like to do now is have a message dialog that asks if the user would like to save when they try to change the selection. If they don't I want to revert it back to the original item in the collection. If they hit cancel I want the selection to focus back on the previously selected item. I am wondering what the best way would be to accomplish this in an MVVM manner?

Currently I have a Model for my customer and my VM fills a collection of Customers that the listbox is bound to. So is there a way to handle the selection changed event on the VM that would include being able to manipulate the selectedIndex of the listbox? Here is my code so you can see what I am doing.

                if (value != _selectedAccount)
                {
                    MessageBoxResult mbr = MessageBox.Show("Do you want to save your work?", "Save", MessageBoxButton.YesNoCancel);
                    if (mbr == MessageBoxResult.Yes)
                    {
                        //Code to update corporate
                        Update_Corporate();
                        _preSelectedAccount = value;
                        _selectedAccount = value;
                    }
                    if (mbr == MessageBoxResult.No)
                    {
                        //Do Stuff

                    }
                    if (mbr == MessageBoxResult.Cancel)
                    {

                        SelectedAccount = _preSelectedAccount;
                        NotifyPropertyChanged("SelectedAccount");
                    }

                }

2 Answers 2

2

the best way you can catch the changed event is to bind the SelectedItem of the listbox to another property in your view model, then on the set you can do what you need to do:

private Customer selectedCustomer;
public Customer SelectedCustomer
{
    get { return selectedCustomer; }
    set
    {
        if (selectedCustomer== value) return;
        selectedCustomer = value;
        RaisePropertyChanged("SelectedCustomer");
        // Do your stuff here
    }
}

This is an example using MVVM light (RaisePropertyChanged).

Sign up to request clarification or add additional context in comments.

Comments

1

XAML:

<ListBox ItemsSource="{Binding Customers}" SelectedItem="{Binding SelectedCustomer}" DisplayMemberPath="CustomerName"/>

ViewModel:

private Customer selectedCustomer;
public Customer SelectedCustomer
{
  get
  {
    return selectedCustomer;
  }
  set
  {
    if (value != selectedCustomer)
    {
      var originalValue = selectedCustomer;
      selectedCustomer = value;
      dlgConfirm dlg = new dlgConfirm();
      var result = dlg.ShowDialog();
      if (!result.HasValue && result.Value)
      {
        Application.Current.Dispatcher.BeginInvoke(
            new Action(() =>
            {
                selectedCustomerr = originalValue;
                OnPropertyChanged("SelectedCustomer");
            }),
            System.Windows.Threading.DispatcherPriority.ContextIdle,
            null
        );
      }
      else
        OnPropertyChanged("SelectedCustomer");
    }
  }
}

Taken/further info from here.

3 Comments

My solution looks quite similar to this, I have one issue. When the user presses cancel I want the selection to remain where it was and I can do that but the view highlights the item that the user clicks on but all of the account information on the rest of the form stays as if the cancel worked.
hmm, looks like you need to use the dispatcher to go back and change to the original after the selectedindex is updated. above code updated to reflect this, more info here.
Thanks alot for the link, I read the comments on the post and ended up using a different approach that had been posted below it using the CollectionViewSource. Just want to mention that if I put the IsAsync property to true on the binding that the method above worked but seemd slow.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.