Xamarin.Forms
Xamarin.Forms copied to clipboard
[Bug] PushAsync overrides manually set BindingContext
Description
Shell project
Whenever a content page has a manually set binding context, i.e.
ContentPage page = new SomePage();
page.BindingContext = someViewModel;
which we then push via
Shell.Current.Navigation.PushAsync(page);
That page's BindingContext gets overwritten with the inherited binding context.
This was not an issue on the versions prior to Xamarin Forms 5.0.
Interestingly enough - PushModalAsync seems to behave as expected, carries over the correct BindingContext.
It also looks like PushAsync doesn't reuse the page you pass it, but it creates a new instance of the page you pass it in, which explains why it defaults to the inherited BindingContext. You can tell that is the case, because SomePage
's constructor gets hit whenever we do Navigation.PushAsync(page)
, whereas it does not get hit whenever we do Navigation.PushModalAsync(page)
.
Steps to Reproduce
- Create a page
- Manually assign a binding context to it
- Navigation.PushAsync(page)
- page BindingContext gets overwritten
Expected Behavior
Binding Context does not change from the manually set one.
Handle BindingContext like Navigation.PushModalAsync
Actual Behavior
Binding Context changes to the inherited one from the navigation stack.
Basic Information
- Version with issue Xamarin 5+
- Last known good version Xamarin 4.8
- Platform Target Frameworks:
- iOS: 12.2+
- Android: Android 5.0+
Environment
Microsoft Visual Studio Professional 2019 Version 16.8.4 VisualStudio.16.Release/16.8.4+30907.101 Microsoft .NET Framework Version 4.8.04084
Show/Hide Visual Studio info
Xamarin 16.8.000.261 (d16-8@bb99248)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.
Xamarin Designer 16.8.0.507 (remotes/origin/d16-8@e87b24884)
Visual Studio extension to enable Xamarin Designer tools in Visual Studio.
Xamarin Templates 16.8.112 (86385a3)
Templates for building iOS, Android, and Windows apps with Xamarin and Xamarin.Forms.
Xamarin.Android SDK 11.1.0.26 (d16-8/a36ce73)
Xamarin.Android Reference Assemblies and MSBuild support.
Mono: 5e9cb6d
Java.Interop: xamarin/java.interop/d16-8@79d9533
ProGuard: Guardsquare/proguard/proguard6.2.2@ebe9000
SQLite: xamarin/sqlite/3.32.1@1a3276b
Xamarin.Android Tools: xamarin/xamarin-android-tools/d16-8@2fb1cbc
Xamarin.iOS and Xamarin.Mac SDK 14.8.0.3 (c51fabee8)
Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.
Screenshots
Stack trace: Manually setting the binding context
Manually setting the binding context stack trace
0x1 in Solution.Project.SomePage.OnBindingContextChanged at C:/Solution/Project/SomePage.xaml.cs:36,13
0x10 in Xamarin.Forms.BindableObject.BindingContextPropertyChanged at D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:550,4
0x12E in Xamarin.Forms.BindableObject.SetValueActual at D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:512,5
0x17C in Xamarin.Forms.BindableObject.SetValueCore at D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:446,5
0x61 in Xamarin.Forms.BindableObject.SetValue at D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:374,4
0x5 in Xamarin.Forms.BindableObject.SetValue at D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:349,68
0x7 in Xamarin.Forms.BindableObject.set_BindingContext at D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:31,11
Stack trace: Once navigation is complete, the binding context gets changed
Navigation Complete stack trace
0x1 in Solution.Project.SomePage.OnBindingContextChanged at C:/Solution/Project/SomePage.xaml.cs:36,13
0x63 in Xamarin.Forms.BindableObject.SetInheritedBindingContext at D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:247,4
0x2 in Xamarin.Forms.Element.SetChildInheritedBindingContext at D:\a\1\s\Xamarin.Forms.Core\Element.cs:479,4
0xD5 in Xamarin.Forms.Element.set_Parent at D:\a\1\s\Xamarin.Forms.Core\Element.cs:197,6
0x2 in Xamarin.Forms.Element.OnChildAdded at D:\a\1\s\Xamarin.Forms.Core\Element.cs:324,4
0x2 in Xamarin.Forms.ShellSection.OnChildAdded at D:\a\1\s\Xamarin.Forms.Core\Shell\ShellSection.cs:642,4
0xE in Xamarin.Forms.ShellSection.AddPage at D:\a\1\s\Xamarin.Forms.Core\Shell\ShellSection.cs:984,4
0x60 in Xamarin.Forms.ShellSection.OnPushAsync at D:\a\1\s\Xamarin.Forms.Core\Shell\ShellSection.cs:834,4
0x8A in Xamarin.Forms.ShellSection.PushStackOfPages at D:\a\1\s\Xamarin.Forms.Core\Shell\ShellSection.cs:588,6
0x33 in System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start<Xamarin.Forms.ShellSection.<PushStackOfPages>d__70> at /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:316,17
0x35 in Xamarin.Forms.ShellSection.PushStackOfPages
0x51F in Xamarin.Forms.ShellSection.GoToAsync at D:\a\1\s\Xamarin.Forms.Core\Shell\ShellSection.cs:571,4
0x33 in System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start<Xamarin.Forms.ShellSection.<GoToAsync>d__69> at /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:316,17
0x46 in Xamarin.Forms.ShellSection.GoToAsync
0x7FD in Xamarin.Forms.ShellNavigationManager.GoToAsync at D:\a\1\s\Xamarin.Forms.Core\Shell\ShellNavigationManager.cs:166,5
0x33 in System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start<Xamarin.Forms.ShellNavigationManager.<GoToAsync>d__11> at /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:316,17
0x2D in Xamarin.Forms.ShellNavigationManager.GoToAsync
0x45 in Xamarin.Forms.ShellSection.NavigationImpl.OnPushAsync at D:\a\1\s\Xamarin.Forms.Core\Shell\ShellSection.cs:1116,5
0x16 in Xamarin.Forms.Internals.NavigationProxy.PushAsync at D:\a\1\s\Xamarin.Forms.Core\NavigationProxy.cs:117,4
0x8 in Xamarin.Forms.Shell.NavigationImpl.OnPushAsync at D:\a\1\s\Xamarin.Forms.Core\Shell\Shell.cs:1302,69
0x16 in Xamarin.Forms.Internals.NavigationProxy.PushAsync at D:\a\1\s\Xamarin.Forms.Core\NavigationProxy.cs:117,4
Reproduction Link
Watch for:
- BuggedPage.xaml;
- BuggedPage.xaml.cs;
- BuggedPageViewModel.cs;
- AppShellViewModel.cs;
- AppShell.xaml;
- AppShell.xaml.cs
Workaround
None, I tried setting the binding context of the referenced page object after the PushAsync. However, changing the binding context on that page element, doesn't actually seem to prompt OnBIndingContextChanged/Change the binding context at all.
How is it overwritten? I configure the contexts like this and I see all my data well, how can I reproduce the error
@GeorgeVelikov Could you attach a small sample where reproduce the issue?
Apologies for the delay. I'll create a reproduction project today/tomorrow and tag you once I have it ready
@jsuarezruiz @angelru
Watch for:
- BuggedPage.xaml;
- BuggedPage.xaml.cs;
- BuggedPageViewModel.cs;
- AppShellViewModel.cs;
- AppShell.xaml;
- AppShell.xaml.cs
any updates on this?
Same problem here