ConfirmNavigationRequest() called twice when DataContext = this

Topics: Prism v4 - WPF 4
Mar 6, 2012 at 12:52 PM
Edited Mar 6, 2012 at 12:55 PM

My question @ StackOverflow: http://stackoverflow.com/q/9569542/389966

I'm using Prism and my views implement IConfirmNavigationRequest in order to enable them to perform validations and cancel the navigation if required.

My problem is that I have several views which don't use MVVM, and define DataContext = this. Doing so causes Prism to call my view's ConfirmNavigationRequest() twice, which means I ask for the user's response twice.

Basically what's going on is this:

  1. Prism checks if the view implements IConfirmNavigationRequest and calls ConfirmNavigationRequest() on it if it does.
  2. The user is asked whether he'd like to continue.
  3. The user clicks OK and ConfirmNavigationRequest() returns true.
  4. Prism checks if the viewmodel (in my case, it's the view again) implements IConfirmNavigationRequest and calls ConfirmNavigationRequest() on it if it does.
  5. The user is asked again whether he'd like to continue.

As you can see, Prism asks my view for confirmation twice because it queries both the view and the viewmodel.

So my question is, how can I prevent this from happening or how can I detect which call is which so I can ignore one of them? I thought about investigating the continuationCallback parameter, but I don't like this solution so much since it's not unlikely it'll break in the next versions of Prism.

Any help will be appreciated.

Thanks

Developer
Mar 6, 2012 at 4:00 PM

Hi,

As mentioned in the thread INavigationAware issue when DataContext of View is itself, a possible approach could be setting the DataContext property of the "root" visual element of the view instead of the view's DataContext property. For example, if you have a Grid as the "root" visual element of your view:

<UserControl ...>
    <Grid Name="LayoutRoot">

        ...

    </Grid>
</UserControl>

Then, you can set its DataContext property like this:

public partial class MyView : UserControl
{
    public MyView()
    {
        InitializeComponent();
        this.LayoutRoot.DataContext = this;

        // This is optional and might not be required.
        this.DataContext = null;
    }
}
Based on my understanding, your view's DataContext will not be the view itself, avoiding the problem of the ConfirmNavigationRequest method being invoked twice, while being able to use your view as the DataContext for its visual elements.

I hope you find this useful,

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

Mar 6, 2012 at 4:27 PM

Thanks for the helpful reply. This is definitely something I will consider doing.

However, if someone has a solution that doesn't involve making changes to the views, I'd be happy to hear about it.

Thanks again.

Aug 30, 2012 at 6:53 PM
Edited Aug 30, 2012 at 7:07 PM

Hi! just checking if anyone has found a better solution than this. I am also having same problem. This looks like a bug in PRISM implementation of INavigationAware that needs to be fixed.