IConfirmNavigationRequest methods are not being executed

Aug 27, 2012 at 9:36 PM
Edited Aug 28, 2012 at 6:38 AM

I implemented the IConfirmNavigationRequest in the ViewModel of a View.

The problem is that the interface methods OnNavigatedFrom, OnNavigatedTo, etc. are not being executed when I perform RequestNavigate.

But if I implement them in a view's code-behind file, they get executed properly. Is there a reason for that?

How can I get these method get executed from the ViewModel?

I'm using the MVVM approach in which each buton has a command that is executed in the viewmodel. Navigation is being requested from a button..


Developer
Aug 28, 2012 at 1:54 PM

Hi Rafael,

Based on my understanding, you should be able to implement the IConfirmNavigationRequest on your view or view model class without problems. As an example, I believe you could check the View-Switching Navigation Quick Start, which implements this interface in its ComposeEmailViewModel class. Perhaps it could be useful to compare the differences with your own implementation.

Regards,

Agustin Adami
http://blogs.southworks.net/aadami

Aug 28, 2012 at 6:48 PM
Edited Aug 28, 2012 at 6:57 PM

Allow me to show you what I have so far, I guess you will detect what I'm doing wrong.

In my view I have a button whose sole purpose is to switch views, this button is bound to a DelegateCommand in the view's viewmodel.

The view swtching is working properly, but the IConfirmNavigationRequest methods are not been executed.

Here's the view model:

public class CustomerSummaryViewModel : INotifyPropertyChanged, IConfirmNavigationRequest {

   IRegionManager _regionManager;
   IViewsCollection Views;
   string _nextView = "CustomerOrdersView";

   public CustomerSummaryViewModel(IRegionManager regionManager) {
      ChangeView = new DelegateCommand(OnChangeView, CanChangeView);

      this._regionManager = regionManager;
   }

   public DelegateCommand ChangeView {
      get;
      private set;
   }

   private bool CanChangeView() {
      return true;
   }

   private void OnChangeView() {

      // THIS CALL TO REQUESTNAVIGATE SHOULD CALL IConfirmNavigationRequest METHODS, BUT THAT'S NOT HE CASE
      _regionManager.RequestNavigate
      (
            "DetailsRegion",
            new Uri(_nextView, UriKind.Relative),
            a => {
            }
      );

      switch (_nextView) {
         case "CustomerDetailsView":
         _nextView = "CustomerOrdersView";
         break;

         case "CustomerOrdersView":
         _nextView = "CustomerDetailsView";
         break;
      }
   }

   void PostNavigationCallback(NavigationResult navigationResult) {
      if (navigationResult.Result == true)
         MessageBox.Show("Navigation Successful");
      else
         MessageBox.Show("Navigation Failed");
   }

   private Customer currentCustomer;

   public Customer CurrentCustomer {
      get {
         return this.currentCustomer;
      }
      set {
         this.currentCustomer = value;
         this.NotifyPropertyChanged("CurrentCustomer");
      }
   }

   #region INotifyPropertyChanged Members

   public event PropertyChangedEventHandler PropertyChanged;

   private void NotifyPropertyChanged(string propertyName) {
      if (this.PropertyChanged != null) {
         this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
      }
   }

   #endregion

   #region IConfirmNavigationRequest Members

   public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback) {
      MessageBoxResult messageBoxResult =
            MessageBox.Show("Should Navigate from Current View?", "Navigate", MessageBoxButton.OKCancel);

      bool shouldNavigateFromCurrentView = messageBoxResult.HasFlag(MessageBoxResult.OK);

      continuationCallback(shouldNavigateFromCurrentView);
   }

   #endregion

   #region INavigationAware Members

   public bool IsNavigationTarget(NavigationContext navigationContext) {
      return true;
   }

   public void OnNavigatedFrom(NavigationContext navigationContext) {
      MessageBox.Show("We are within CustomerSummaryViewModel");
   }

   public void OnNavigatedTo(NavigationContext navigationContext) {
      MessageBox.Show("We are within CustomerSummaryViewModel");
   }

   #endregion
}

Here's the entire ptoject

https://skydrive.live.com/#cid=228822BB183339A9&id=228822BB183339A9%21234

 

Rafael

Developer
Aug 28, 2012 at 8:51 PM

Hi,

If I understood your scenario correctly what you are saying is that when you navigate to the CustomerDetailsView or CustomerOrdersView (in the DetailsRegion) the IConfirmNavigationRequest methods of the CustomerSummaryViewModel (which request the navigation) are not being executed.

However, this is not an "unusual" behavior: When a navigation request is performed, Prism invokes the IConfirmNavigationRequest methods of the corresponding views and view models contained in the region where the navigation is performed.

For example, in this case when you perform a navigation request to the "DetailsRegion," Prism would invoke the IConfirmNavigationRequest methods of the views and view models contained in it, that is, the CustomerDatailsView and CustomerOrdersView (in the sample you provided those views don't implement IConfirmNavigationRequest).

You can find more information about this in the following section of Prism's documentation:

Also, I believe you can find the View-Switching Navigation Quick Start mentioned by Agustin interesting.

As a side note, it seems that you are not using the ConfirmNavigationRequest method. If that is so and you want to implement only the OnNavigateTo, OnNavigateFrom and IsNavigationTarget methods, I believe you could implement the INavigationAware interface instead of the IConfirmNavigationRequest.

Regards,

Damian Cherubini
http://blogs.southworks.net/dcherubini