Xamarin.Forms icon indicating copy to clipboard operation
Xamarin.Forms copied to clipboard

[Bug] PushAsync overrides manually set BindingContext

Open GeorgeVelikov opened this issue 3 years ago • 5 comments

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

  1. Create a page
  2. Manually assign a binding context to it
  3. Navigation.PushAsync(page)
  4. 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 image

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 image

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

Reproduction14176.zip

Watch for:

  • BuggedPage.xaml;
  • BuggedPage.xaml.cs;
  • BuggedPageViewModel.cs;
  • AppShellViewModel.cs;
  • AppShell.xaml;
  • AppShell.xaml.cs

image

image

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.

GeorgeVelikov avatar Apr 19 '21 11:04 GeorgeVelikov

How is it overwritten? I configure the contexts like this and I see all my data well, how can I reproduce the error

angelru avatar Apr 20 '21 13:04 angelru

@GeorgeVelikov Could you attach a small sample where reproduce the issue?

jsuarezruiz avatar May 03 '21 13:05 jsuarezruiz

Apologies for the delay. I'll create a reproduction project today/tomorrow and tag you once I have it ready

GeorgeVelikov avatar May 20 '21 16:05 GeorgeVelikov

@jsuarezruiz @angelru

Reproduction14176.zip

Watch for:

  • BuggedPage.xaml;
  • BuggedPage.xaml.cs;
  • BuggedPageViewModel.cs;
  • AppShellViewModel.cs;
  • AppShell.xaml;
  • AppShell.xaml.cs

image

image

GeorgeVelikov avatar May 20 '21 16:05 GeorgeVelikov

any updates on this?

borrmann avatar Aug 24 '22 09:08 borrmann

Same problem here

stefanomasseroli avatar Dec 05 '22 11:12 stefanomasseroli