Navigation data is retained and also presented to IQueryAttributable on Back navigation.
See original GitHub issueDescription
I’m using Shell with my MAUI app and am passing parameters during navigation with Shell.GoToAsync() using the Dictionary<string, object> and the IQueryAttributable interface as discussed in the MS docs.
var navigationParameter = new Dictionary<string, object>
{
{ "Bear", animal }
};
await Shell.Current.GoToAsync($"beardetails", navigationParameter);
public class BearDetailViewModel : IQueryAttributable, INotifyPropertyChanged
{
public Animal Bear{ get; private set; }
public void ApplyQueryAttributes(IDictionary<string, object> query)
{
Bear= query["Bear"] as Animal;
OnPropertyChanged("Bear");
}
...
}
I noted that my bindings and initialization code for the ViewModel kept being re-executed when I would Navigate Back to the parent page. It appears that any data that’s passed as navigation parameters is retained in memory for the life of the page and is subsequently returned to that page during a “Navigate Back” operation. Overriding the back button operation with code that doesn’t pass any parameters didn’t change the result. Such as this:
<Shell.BackButtonBehavior>
<BackButtonBehavior
Command="{Binding BackCommand, Mode=OneTime, Source={x:Reference self}}"/>
</Shell.BackButtonBehavior>
}
this.BackCommand = new Command( this.OnBackPressed );
}
private async void OnBackPressed()
{
await Shell.Current.GoToAsync( ".." );
}
Any attempt to clear or supply a different set of data via the method call simply serves to add to the already stored query data. Thus:
Shell.Current.GoToAsync( "..", new Dictionary<string, object> { {"w", new object()} });
results in the “w” parameter being added to the current store of parameters. And now “w” and “Bear” are retained until the page is removed from the stack.
Maybe I’m used to external navigation paradigms but my presumption was that the data was transient for the life of the navigation operation only. Thus the retention of data was not expected. The docs fail to mention anything about the data being retained for the life for the page as well. Off the cuff this seems like a poor model as it increases memory footprint and possibly has unintended consequences if any system resources were shuttled as parameters.
Steps to Reproduce
Pass parameters to any page as you navigate down a hierarchy. When the back button is pressed the query data that was passed to any particular page on the initial navigation TO that page is returned via the IQueryAttributable interface.
Link to public reproduction project repository
https://github.com/bakerhillpins/Issues/tree/NetMauiIssue10294
Version with bug
6.0.486 (current)
Last version that worked well
Unknown/Other
Affected platforms
iOS, Android, Windows, macOS
Affected platform versions
Android 9.0, API 28
Did you find any workaround?
As the Query parameters are passed via IDictionary<string, object> query the author would need to manually cleanup individual resources with IDictionary<string, object>.Remove() or IDictionary<string, object>.Clear() in an implementation of the IQueryAttributable interface:
public class BearDetailViewModel : IQueryAttributable, INotifyPropertyChanged
{
public Animal Bear{ get; private set; }
public void ApplyQueryAttributes(IDictionary<string, object> query)
{
Bear= query["Bear"] as Animal;
OnPropertyChanged("Bear");
query.Clear();
}
...
}
If one was using the Attribute:
[QueryProperty(nameof(Name), "name")]
[QueryProperty(nameof(Location), "location")]
they’d be forced to implement the interface to remove the data. Or, I suppose their property setters must qualify any update with a test for != or their bindings would re-execute when they returned to the page.
Relevant log output
No response
Issue Analytics
- State:
- Created a year ago
- Reactions:2
- Comments:52 (20 by maintainers)

Top Related StackOverflow Question
A workaround for me : clear query dictionary after receiving it, I am able to do it in view model class that implement
IQueryAttributable:`public void ApplyQueryAttributes(IDictionary<string, object> query) { if (query.ContainsKey(“querydataKey”)) { //process here query[“querydataKey”]
}
//clear the query to release the data query. Clear(); }`
IQueryAttributablework nicely withObservableObjectofCommunity toolkit MAUI mvvm hope this helps some that tries to send data througth appShell page navigation !I hear you but I don’t agree because I’m not actually “navigating” to a new page as you describe above. The Pop/Back operation doesn’t take in a
Uri,It simply removes aViewfrom the z-order and returns us to the same page (same instance) we were viewing previously. Nothing new was created. I’m popping a view off the stack and I didn’t apply any navigation parameters to that action. In your example you show navigation topagetwice. There’s 2 specific actions you’ve requested in there.Pageobject. In MAUI this would result in a stack of /Page/OtherPage/Page. This issue discusses going from /Page/OtherPage back to /Page, so we’re not increasing the z-order.?foo=bar). In this situation you’ve actually requested a different instance of theBarobject to be supplied to each navigation operation and that’s not what’s happening here. The pop action results in the same instances of data being delivered to the return operation that was applied when the view was initially navigated to.