uno
uno copied to clipboard
[Android] `x:Bind` mode `OneTime` doesn't work because `Page` is loaded early when using `NativeFramePresenter`
Current behavior
x:Bind
doesn't properly work on Android.
06-16 13:21:39.635 E/Windows.UI.Xaml.Data.BindingExpression(13378): Failed to apply binding to property [DependencyPropertyDetails(Command)] on [Windows.UI.Xaml.Controls.Primitives.ButtonBase] (Specified cast is not valid.) System.InvalidCastException: Specified cast is not valid.
06-16 13:21:39.635 E/Windows.UI.Xaml.Data.BindingExpression(13378): at ApplicationTemplate.Views.Content.HomePage.get_VM () [0x00000] in B:\Repos\xbindSample\src\app\ApplicationTemplate.UWP\Views\Content\Welcome\HomePage.xaml.cs:13
06-16 13:21:39.635 E/Windows.UI.Xaml.Data.BindingExpression(13378): at ApplicationTemplate.Views.Content.HomePage+<>c.<InitializeComponent>b__4_8 (System.Object ___ctx) [0x00000] in B:\Repos\xbindSample\src\app\ApplicationTemplate.Droid\obj\Debug\100\g\XamlCodeGenerator\HomePage_f3d3c6677e835d082815ec6734517a07.g.cs:119
06-16 13:21:39.635 E/Windows.UI.Xaml.Data.BindingExpression(13378): at Windows.UI.Xaml.Data.BindingExpression.Uno.UI.DataBinding.IValueChangedListener.OnValueChanged (System.Object o) [0x00045] in C:\a\1\s\src\Uno.UI\DataBinding\BindingExpression.cs:525
06-16 13:21:39.635 E/Windows.UI.Xaml.Data.BindingExpression(13378):
Expected behavior
x:Bind
is applied properly on all platforms.
How to reproduce it (as minimally and precisely as possible)
Xamarin
- Launch the following sample. xbindSample.zip
- Notice that the button in HomePage.xaml works on UWP and iOS, but not on Android.
.Net 7 Mobile
- Launch the following sample. XBindSampleNet7.zip
- Notice that the button in HomePage.xaml works on WinUI and iOS, but not on Android.
Environment
Nuget Package:
- [x] Uno.UI / Uno.UI.WebAssembly / Uno.UI.Skia
- [x] Uno.WinUI / Uno.WinUI.WebAssembly / Uno.WinUI.Skia
- [ ] Uno.SourceGenerationTasks
- [ ] Uno.UI.RemoteControl / Uno.WinUI.RemoteControl
- [ ] Other:
Nuget Package Version(s):
- 3.6.6
- 4.8.24
Affected platform(s):
- [ ] iOS
- [x] Android
- [ ] WebAssembly
- [ ] WebAssembly renderers for Xamarin.Forms
- [ ] macOS
- [ ] Skia
- [ ] WPF
- [ ] GTK (Linux)
- [ ] Tizen
- [ ] Windows
- [ ] Build tasks
- [ ] Solution Templates
Anything else we need to know?
Thanks for the report.
This is not an x:Bind issue. The DataContext property is not of the proper type (it's ShellViewModel which is why this happens) when read in the VM
property. Could it be a race condition with the assignation of the DataContext
for the page?
I don't know if it's a race condition because it's always the same behavior. The sequence on Android seems (consistently) different than UWP and iOS. I don't mind renaming this issue to reflect the problem rather than the symptom if you want :)
Sure. In all cases, there's something to troubleshoot before this happens, to understand why the DataContext provided here is not the right one, likely in Chinook's code?
The creation sequence of controls may be a bit different on android, and that's not something we can adjust easily. It's probably safer to adapt the code that sets the DataContext.
Yeah that code is here: https://github.com/nventive/Chinook.Navigation/blob/master/src/StackNavigation.Uno/FrameStackNavigator.cs#L188
As we get the Page
instance (after Frame.Navigate
), we set its DataContext.
GitHub
Contribute to nventive/Chinook.Navigation development by creating an account on GitHub.
Thanks. If the DataContext ends up being set to the Shell, this means that it's provided exactly as is. Did you troubleshoot that part ?
Also know that the evaluation of the DataContext is done on Loading. If the DataContext is changed afterwards, which is the case here, it won't get picked up.
Set the binding OneWay, and use this :
public sealed partial class HomePage : Page, INotifyPropertyChanged
{
public HomePage()
{
this.InitializeComponent();
DataContextChanged += (s, e) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("VM"));
}
public HomePageViewModel VM => DataContext as HomePageViewModel;
public event PropertyChangedEventHandler PropertyChanged;
}
This is a side effect of the way the android native presenter works.
@jeromelaban if datacontext changes consistently on every page load on Android, wouldn't this cause all bindings to be evaluated twice? And maybe even have the pages relayout themselves following those binding updates?
Fixing this issue could have major performance improvements. cc @jeanplevesque
The bindings will not be evaluated twice, as the root VM property is initially null because of the cast. It'll be populated once it's set, and won't change unless set explicitly to a different value.
I realize that the default x:Bind
mode (OneTime
) cannot currently work on Android because of this 😕
We will not be able to change this behavior for a while (it touches the objects lifecycle in a big way). If you don't want to have the DataContext propagated to a undesired value, you can set DataContext="{x:Null}"
on the Frame
so it will always keep null for its descendants until overridden locally on a page.
You'll still need to have OneWay
binding, but it'll be changed only once.
Setting DataContext="{x:Null}"
on a parent control doesn't seem to prevent the DataContext propagation. I still get ShellViewModel
before the page view model.
This brings another problem for custom controls that rely on the DataContext.
This bugs forces us to do things such as the following:
Setting the DataContext explicitly should prevent the inheritance. If it still happens, try finding what sets it through the stack trace in the return from the screenshot above.
The call stack shows that it's during the Frame.Navigate
operation.
0x14 in ProjectName.Views.Controls.TabbedListView.OnDataContextChanged at B:\Repos\ProjectName.App\src\app\ProjectName.UWP\Views\Controls\TabbedListView\TabbedListView.cs:149,5 C#
0x17 in Uno.UI.Controls.BindableView.OnDataContextChanged at C:\a\1\s\src\Uno.UI\obj\Release\monoandroid11.0\g\DependencyObjectGenerator\Uno_UI_Controls_BindableView_eefac468be1af0c618115e95339af76c.g.cs:335,9 C#
0x2 in Windows.UI.Xaml.Controls.Control.OnDataContextChanged at C:\a\1\s\src\Uno.UI\UI\Xaml\Controls\Control\Control.cs:755,4 C#
0x7 in Uno.UI.Controls.BindableView.<>c.<.cctor>b__1_0 at C:\a\1\s\src\Uno.UI\obj\Release\monoandroid11.0\g\DependencyObjectGenerator\Uno_UI_Controls_BindableView_eefac468be1af0c618115e95339af76c.g.cs:328,46 C#
0xD in Windows.UI.Xaml.PropertyMetadata.RaisePropertyChanged at C:\a\1\s\src\Uno.UI\UI\Xaml\PropertyMetadata.cs:187,4 C#
0xE3 in Windows.UI.Xaml.DependencyObjectStore.InvokeCallbacks at C:\a\1\s\src\Uno.UI\UI\Xaml\DependencyObjectStore.cs:1681,4 C#
0x6C in Windows.UI.Xaml.DependencyObjectStore.RaiseCallbacks at C:\a\1\s\src\Uno.UI\UI\Xaml\DependencyObjectStore.cs:1591,5 C#
0x1BE in Windows.UI.Xaml.DependencyObjectStore.InnerSetValue at C:\a\1\s\src\Uno.UI\UI\Xaml\DependencyObjectStore.cs:505,6 C#
0x22 in Windows.UI.Xaml.DependencyObjectStore.SetValue at C:\a\1\s\src\Uno.UI\UI\Xaml\DependencyObjectStore.cs:439,5 C#
0x4F in Windows.UI.Xaml.DependencyObjectStore.OnParentPropertyChangedCallback at C:\a\1\s\src\Uno.UI\UI\Xaml\DependencyObjectStore.cs:899,5 C#
0x2C in Windows.UI.Xaml.DependencyObjectStore.CallChildCallback at C:\a\1\s\src\Uno.UI\UI\Xaml\DependencyObjectStore.cs:1716,5 C#
0xA9 in Windows.UI.Xaml.DependencyObjectStore.InvokeCallbacks at C:\a\1\s\src\Uno.UI\UI\Xaml\DependencyObjectStore.cs:1658,7 C#
0x6C in Windows.UI.Xaml.DependencyObjectStore.RaiseCallbacks at C:\a\1\s\src\Uno.UI\UI\Xaml\DependencyObjectStore.cs:1591,5 C#
0x1BE in Windows.UI.Xaml.DependencyObjectStore.InnerSetValue at C:\a\1\s\src\Uno.UI\UI\Xaml\DependencyObjectStore.cs:505,6 C#
0x22 in Windows.UI.Xaml.DependencyObjectStore.SetValue at C:\a\1\s\src\Uno.UI\UI\Xaml\DependencyObjectStore.cs:439,5 C#
0x4F in Windows.UI.Xaml.DependencyObjectStore.OnParentPropertyChangedCallback at C:\a\1\s\src\Uno.UI\UI\Xaml\DependencyObjectStore.cs:899,5 C#
0x26 in Windows.UI.Xaml.DependencyObjectStore.<PropagateInheritedProperties>g__Propagate|145_0 at C:\a\1\s\src\Uno.UI\UI\Xaml\DependencyObjectStore.cs:1347,6 C#
0x3F in Windows.UI.Xaml.DependencyObjectStore.PropagateInheritedProperties at C:\a\1\s\src\Uno.UI\UI\Xaml\DependencyObjectStore.cs:1359,5 C#
0x14 in Windows.UI.Xaml.DependencyObjectStore.RegisterInheritedPropertyChangedCallback at C:\a\1\s\src\Uno.UI\UI\Xaml\DependencyObjectStore.cs:795,4 C#
0x29 in Windows.UI.Xaml.DependencyObjectStore.RegisterInheritedProperties at C:\a\1\s\src\Uno.UI\UI\Xaml\DependencyObjectStore.cs:992,4 C#
0x68 in Windows.UI.Xaml.DependencyObjectStore.TryRegisterInheritedProperties at C:\a\1\s\src\Uno.UI\UI\Xaml\DependencyObjectStore.cs:949,7 C#
0x7D in Windows.UI.Xaml.DependencyObjectStore.set_Parent at C:\a\1\s\src\Uno.UI\UI\Xaml\DependencyObjectStore.cs:154,7 C#
0xC in Windows.UI.Xaml.FrameworkElement.PerformOnLoaded at C:\a\1\s\src\Uno.UI\UI\Xaml\FrameworkElement.Android.cs:49,4 C#
0x1 in Windows.UI.Xaml.FrameworkElement.OnNativeLoaded at C:\a\1\s\src\Uno.UI\UI\Xaml\FrameworkElement.Android.cs:36,5 C#
0x4C in Windows.UI.Xaml.FrameworkElement.PerformOnLoaded at C:\a\1\s\src\Uno.UI\UI\Xaml\FrameworkElement.Android.cs:66,7 C#
0x1 in Windows.UI.Xaml.FrameworkElement.OnNativeLoaded at C:\a\1\s\src\Uno.UI\UI\Xaml\FrameworkElement.Android.cs:36,5 C#
0xA in Uno.UI.UnoViewGroup.n_OnNativeLoaded at C:\a\1\s\src\Uno.UI.BindingHelper.Android\obj\Release\monoandroid11.0\generated\src\Uno.UI.UnoViewGroup.cs:587,4 C#
0x11 in Android.Runtime.DynamicMethodNameCounter.125 C#
0xFFFFFFFFFFFFFFFF in Java.Interop.NativeMethods.java_interop_jnienv_call_nonvirtual_void_method_a C#
0x79 in Java.Interop.JniEnvironment.InstanceMethods.CallNonvirtualVoidMethod C#
0x21 in Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeNonvirtualVoidMethod C#
0x38 in Uno.UI.UnoViewGroup.AddViewFast at C:\a\1\s\src\Uno.UI.BindingHelper.Android\obj\Release\monoandroid11.0\generated\src\Uno.UI.UnoViewGroup.cs:290,5 C#
0xE in Uno.UI.Controls.BindableView.AddView at C:\a\1\s\src\Uno.UI\Controls\BindableView.Android.cs:116,4 C#
0x7 in Windows.UI.Xaml.Controls.UIElementCollection.AddCore at C:\a\1\s\src\Uno.UI\UI\Xaml\UIElementCollection.Android.cs:57,4 C#
0x13 in Windows.UI.Xaml.Controls.UIElementCollection.Add at C:\a\1\s\src\Uno.UI\UI\Xaml\UIElementCollection.cs:65,4 C#
0xAB in Uno.UI.Controls.NativeFramePresenter.UpdateStack at C:\a\1\s\src\Uno.UI\NativeFramePresenter.Android.cs:126,6 C#
0x33 in System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start<Uno.UI.Controls.NativeFramePresenter.<UpdateStack>d__13> at /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:316,17 C#
0x35 in Uno.UI.Controls.NativeFramePresenter.UpdateStack C#
0x40 in Uno.UI.Controls.NativeFramePresenter.InvalidateStack at C:\a\1\s\src\Uno.UI\NativeFramePresenter.Android.cs:102,5 C#
0x33 in System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start<Uno.UI.Controls.NativeFramePresenter.<InvalidateStack>d__12> at /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:316,17 C#
0x25 in Uno.UI.Controls.NativeFramePresenter.InvalidateStack C#
0x1D in Uno.UI.Controls.NativeFramePresenter.OnNavigated at C:\a\1\s\src\Uno.UI\NativeFramePresenter.Android.cs:87,4 C#
0x1C2 in Windows.UI.Xaml.Controls.Frame.InnerNavigateUnsafe at C:\a\1\s\src\Uno.UI\UI\Xaml\Controls\Frame\Frame.cs:400,4 C#
0x3 in Windows.UI.Xaml.Controls.Frame.InnerNavigate at C:\a\1\s\src\Uno.UI\UI\Xaml\Controls\Frame\Frame.cs:281,5 C#
here> 0xC in Windows.UI.Xaml.Controls.Frame.Navigate at C:\a\1\s\src\Uno.UI\UI\Xaml\Controls\Frame\Frame.cs:274,4 C#
0x23 in Chinook.StackNavigation.FrameStackNavigator. at B:\Repos\Chinook.Navigation\src\StackNavigation.Uno\FrameStackNavigator.cs:160,7 C#
0xA5 in Chinook.StackNavigation.FrameStackNavigator.WaitForNavigationResult at B:\Repos\Chinook.Navigation\src\StackNavigation.Uno\FrameStackNavigator.cs:310,5 C#
0x33 in System.Runtime.CompilerServices.AsyncTaskMethodBuilder<Windows.UI.Xaml.Navigation.NavigationEventArgs>.Start<Chinook.StackNavigation.FrameStackNavigator.<WaitForNavigationResult>d__11> at /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:471,17 C#
0x2E in Chinook.StackNavigation.FrameStackNavigator.WaitForNavigationResult C#
0x98 in Chinook.StackNavigation.FrameStackNavigator.<>c__DisplayClass9_0.<InnerNavigateAndGetView<InnerNavigateAndGetView>g__UINavigate|0>d at B:\Repos\Chinook.Navigation\src\StackNavigation.Uno\FrameStackNavigator.cs:158,6 C#
0x33 in System.Runtime.CompilerServices.AsyncTaskMethodBuilder<Windows.UI.Xaml.Controls.Page>.Start<Chinook.StackNavigation.FrameStackNavigator.<>c__DisplayClass9_0.<<InnerNavigateAndGetView>g__UINavigate|0>d> at /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:471,17 C#
0x27 in Chinook.StackNavigation.FrameStackNavigator. C#
0x23 in Windows.UI.Core.CoreDispatcherExtensions.<>c__DisplayClass1_0<Windows.UI.Xaml.Controls.Page>.<RunTaskAsync<RunTaskAsync>g__RunActionUI|0>d at B:\Repos\Chinook.Navigation\src\StackNavigation.Uno\Utils\Extensions\Windows.UI.Core.CoreDispatcher.cs:56,6 C#
0x33 in System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Start<Windows.UI.Core.CoreDispatcherExtensions.<>c__DisplayClass1_0<Windows.UI.Xaml.Controls.Page>.<<RunTaskAsync>g__RunActionUI|0>d> at /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:84,17 C#
0x27 in Windows.UI.Core.CoreDispatcherExtensions.<>c__DisplayClass1_0<Windows.UI.Xaml.Controls. C#
0x5E in Windows.UI.Core.CoreDispatcher.InvokeOperation at C:\a\1\s\src\Uno.UWP\UI\Core\CoreDispatcher.cs:368,5 C#
0x2 in Windows.UI.Core.CoreDispatcher.InvokeOperationSafe at C:\a\1\s\src\Uno.UWP\UI\Core\CoreDispatcher.cs:332,5 C#
0xAB in Windows.UI.Core.CoreDispatcher.DispatchItems at C:\a\1\s\src\Uno.UWP\UI\Core\CoreDispatcher.cs:294,6 C#
0x6 in Windows.UI.Core.CoreDispatcher.CoreDispatcherImplementor.Java.Lang.IRunnable.Run at C:\a\1\s\src\Uno.UWP\UI\Core\CoreDispatcher.Android.cs:151,5 C#
0x8 in Java.Lang.IRunnableInvoker.n_Run C#
0x11 in Android.Runtime.DynamicMethodNameCounter.4 C#
Setting the DataContext to null explicitly during the constructor should be enough to prevent the propagation.
Do you mean in the constructor of each page? 😕
Yes, as a workaround. For now it's not something we can fix without major changes.
@jeanplevesque You can also try setting the DataContext
to null on the Frame
so that the inheritance chain is stopped.
@jeromelaban you mean like this?
It doesn't seem to change the behavior on Android. ☹
It should be enough, but if the datacontext is still propagated, it means that it's available in an intermediate control? Try setting it in codebehind, to be sure.
My bad, it does stop the DataContext propagation, but the binding still doesn't work.
I get a NullReferenceException
.
(It seems that with later Uno.UI versions, we don't get the Failed to apply binding to property
log but instead get a NullReferenceException
?)
Thanks. That's still caused by the page being loaded too early, and the only way to fix that is to set the DataContext on the Page before adding it to the tree, something you can't do with frame.
With DataContext="{x:Null}"
[ApplicationTemplate.Views.Startup] Starting startup.
[ApplicationTemplate.CoreStartup] Starting core startup.
[ApplicationTemplate.CoreStartup] Starting services (isFirstStart: true).
Loaded assembly: /data/data/com.nventive.internal.applicationtemplate/files/.__override__/System.Runtime.Serialization.dll [External]
[Chinook.SectionsNavigation.FrameSectionsNavigator] Starting 'SetActiveSection' operation for section 'Login'.
Loaded assembly: /data/data/com.nventive.internal.applicationtemplate/files/.__override__/System.Data.dll [External]
[ApplicationTemplate.Views.Startup] Starting view services (isFirstStart: true).
Loaded assembly: Anonymously Hosted DynamicMethods Assembly [External]
[Choreographer] Skipped 36 frames! The application may be doing too much work on its main thread.
[icationtemplat] Accessing hidden field Landroid/widget/TextView;->mEditor:Landroid/widget/Editor; (unsupported, reflection, allowed)
[0:] The Bindable attribute is missing and the type [ApplicationTemplate.Presentation.ShellViewModel] is not known by the MetadataProvider. Reflection was used instead of the binding engine and generated static metadata. Add the Bindable attribute to prevent this message and performance issues.
[Chinook.DynamicMvvm.ViewModelBase] ViewModel 'ShellViewModel' created.
[Chinook.DynamicMvvm.ViewModelBase] ViewModel 'MenuViewModel' created.
[0:] The Bindable attribute is missing and the type [ApplicationTemplate.Presentation.MenuViewModel] is not known by the MetadataProvider. Reflection was used instead of the binding engine and generated static metadata. Add the Bindable attribute to prevent this message and performance issues.
[Chinook.DynamicMvvm.ViewModelBase] ViewModel 'DiagnosticsOverlayViewModel' created.
[0:] The Bindable attribute is missing and the type [ApplicationTemplate.Presentation.DiagnosticsOverlayViewModel] is not known by the MetadataProvider. Reflection was used instead of the binding engine and generated static metadata. Add the Bindable attribute to prevent this message and performance issues.
[0:] The Bindable attribute is missing and the type [ApplicationTemplate.Presentation.CountersData] is not known by the MetadataProvider. Reflection was used instead of the binding engine and generated static metadata. Add the Bindable attribute to prevent this message and performance issues.
[Chinook.DynamicMvvm.ViewModelBase] ViewModel 'HttpDebuggerViewModel' created.
[0:] The Bindable attribute is missing and the type [ApplicationTemplate.Presentation.HttpDebuggerViewModel] is not known by the MetadataProvider. Reflection was used instead of the binding engine and generated static metadata. Add the Bindable attribute to prevent this message and performance issues.
[Chinook.SectionsNavigation.FrameSectionsNavigator] Finished 'SetActiveSection' operation for section 'Login'.
[ApplicationTemplate.Views.Startup] Started view services.
[Nventive.Persistence.KeyStoreSettingsStorage] Keystore loaded.
[Nventive.Persistence.KeyStoreSettingsStorage] Retrieved value for key 'ApplicationSettings'.
[Chinook.StackNavigation.FrameStackNavigator] Starting 'Navigate' operation to 'ApplicationTemplate.Presentation.DadJokesPageViewModel'.
[Chinook.DynamicMvvm.ViewModelBase] ViewModel 'DadJokesPageViewModel' created.
>>>>> **System.NullReferenceException:** 'Object reference not set to an instance of an object.'
[0:] The Bindable attribute is missing and the type [ApplicationTemplate.Presentation.DadJokesPageViewModel] is not known by the MetadataProvider. Reflection was used instead of the binding engine and generated static metadata. Add the Bindable attribute to prevent this message and performance issues.
>>>>> [ApplicationTemplate.Views.Content.DadJokesPage] DadJokesPage_DataContextChanged: ApplicationTemplate.Presentation.DadJokesPageViewModel
[Chinook.StackNavigation.FrameStackNavigator] Finished 'Navigate' operation to 'ApplicationTemplate.Presentation.DadJokesPageViewModel'.
[Chinook.SectionsNavigation.FrameSectionsNavigator] Starting 'SetActiveSection' operation for section 'Home'.
[Choreographer] Skipped 7479 frames! The application may be doing too much work on its main thread.
[Chinook.SectionsNavigation.FrameSectionsNavigator] Finished 'SetActiveSection' operation for section 'Home'.
[ApplicationTemplate.CoreStartup] Started services.
[ApplicationTemplate.CoreStartup] Started core startup.
[ApplicationTemplate.Views.Startup] Started startup.
Without DataContext="{x:Null}"
[ApplicationTemplate.Views.Startup] Starting startup.
[ApplicationTemplate.CoreStartup] Starting core startup.
[ApplicationTemplate.CoreStartup] Starting services (isFirstStart: true).
Loaded assembly: /data/data/com.nventive.internal.applicationtemplate/files/.__override__/System.Runtime.Serialization.dll [External]
Loaded assembly: /data/data/com.nventive.internal.applicationtemplate/files/.__override__/System.Data.dll [External]
[Chinook.SectionsNavigation.FrameSectionsNavigator] Starting 'SetActiveSection' operation for section 'Login'.
[ApplicationTemplate.Views.Startup] Starting view services (isFirstStart: true).
Loaded assembly: Anonymously Hosted DynamicMethods Assembly [External]
[Choreographer] Skipped 46 frames! The application may be doing too much work on its main thread.
[icationtemplat] Accessing hidden field Landroid/widget/TextView;->mEditor:Landroid/widget/Editor; (unsupported, reflection, allowed)
[OpenGLRenderer] Davey! duration=771ms; Flags=1, FrameTimelineVsyncId=662055, IntendedVsync=719524778645526, Vsync=719525289756632, InputEventId=0, HandleInputStart=719525296662730, AnimationStart=719525296667490, PerformTraversalsStart=719525296668426, DrawStart=719525529633758, FrameDeadline=719524795245526, FrameInterval=719525296534637, FrameStartTime=11111111, SyncQueued=719525536671763, SyncStart=719525536813934, IssueDrawCommandsStart=719525537619720, SwapBuffers=719525548994110, FrameCompleted=719525550627492, DequeueBufferDuration=8667, QueueBufferDuration=1556966, GpuCompleted=719525550070160, SwapBuffersCompleted=719525550627492, DisplayPresentTime=1,
[Chinook.DynamicMvvm.ViewModelBase] ViewModel 'ShellViewModel' created.
[0:] The Bindable attribute is missing and the type [ApplicationTemplate.Presentation.ShellViewModel] is not known by the MetadataProvider. Reflection was used instead of the binding engine and generated static metadata. Add the Bindable attribute to prevent this message and performance issues.
[Chinook.DynamicMvvm.ViewModelBase] ViewModel 'MenuViewModel' created.
[0:] The Bindable attribute is missing and the type [ApplicationTemplate.Presentation.MenuViewModel] is not known by the MetadataProvider. Reflection was used instead of the binding engine and generated static metadata. Add the Bindable attribute to prevent this message and performance issues.
[Chinook.DynamicMvvm.ViewModelBase] ViewModel 'DiagnosticsOverlayViewModel' created.
[0:] The Bindable attribute is missing and the type [ApplicationTemplate.Presentation.DiagnosticsOverlayViewModel] is not known by the MetadataProvider. Reflection was used instead of the binding engine and generated static metadata. Add the Bindable attribute to prevent this message and performance issues.
[0:] The Bindable attribute is missing and the type [ApplicationTemplate.Presentation.CountersData] is not known by the MetadataProvider. Reflection was used instead of the binding engine and generated static metadata. Add the Bindable attribute to prevent this message and performance issues.
[Chinook.DynamicMvvm.ViewModelBase] ViewModel 'HttpDebuggerViewModel' created.
[0:] The Bindable attribute is missing and the type [ApplicationTemplate.Presentation.HttpDebuggerViewModel] is not known by the MetadataProvider. Reflection was used instead of the binding engine and generated static metadata. Add the Bindable attribute to prevent this message and performance issues.
[Chinook.SectionsNavigation.FrameSectionsNavigator] Finished 'SetActiveSection' operation for section 'Login'.
[ApplicationTemplate.Views.Startup] Started view services.
[Nventive.Persistence.KeyStoreSettingsStorage] Keystore loaded.
[Nventive.Persistence.KeyStoreSettingsStorage] Retrieved value for key 'ApplicationSettings'.
[Chinook.StackNavigation.FrameStackNavigator] Starting 'Navigate' operation to 'ApplicationTemplate.Presentation.DadJokesPageViewModel'.
[Chinook.DynamicMvvm.ViewModelBase] ViewModel 'DadJokesPageViewModel' created.
>>>>> [ApplicationTemplate.Views.Content.DadJokesPage] DadJokesPage_DataContextChanged: ApplicationTemplate.Presentation.ShellViewModel
>>>>> **System.NullReferenceException:** 'Object reference not set to an instance of an object.'
[0:] The Bindable attribute is missing and the type [ApplicationTemplate.Presentation.DadJokesPageViewModel] is not known by the MetadataProvider. Reflection was used instead of the binding engine and generated static metadata. Add the Bindable attribute to prevent this message and performance issues.
>>>>> [ApplicationTemplate.Views.Content.DadJokesPage] DadJokesPage_DataContextChanged: ApplicationTemplate.Presentation.DadJokesPageViewModel
[Choreographer] Skipped 327 frames! The application may be doing too much work on its main thread.
[Chinook.StackNavigation.FrameStackNavigator] Finished 'Navigate' operation to 'ApplicationTemplate.Presentation.DadJokesPageViewModel'.
[Chinook.SectionsNavigation.FrameSectionsNavigator] Starting 'SetActiveSection' operation for section 'Home'.
[Chinook.SectionsNavigation.FrameSectionsNavigator] Finished 'SetActiveSection' operation for section 'Home'.
[ApplicationTemplate.CoreStartup] Started services.
[ApplicationTemplate.CoreStartup] Started core startup.
[ApplicationTemplate.Views.Startup] Started startup.
I get the same NullReferenceException
when setting the DataContext
to null
directly in the code behind of the page like this.
Thanks. Then there's no current known workaround for this at this point.
Related to https://github.com/unoplatform/uno/issues/11270
@jeanplevesque would you have an updated version of the repro sample that uses net6/net7? Thanks!
@jeromelaban I updated the description to include a repro that targets .Net 7 mobile. (It's very similar to the Xamarin sample.)
Thanks for the updated sample.
I've tested again the workaround I suggested in https://github.com/unoplatform/uno/issues/6285#issuecomment-863324485, but slightly simplified:
public sealed partial class HomePage : Page
{
public HomePage()
{
this.InitializeComponent();
/* Workaround for https://github.com/unoplatform/uno/issues/6285 */
DataContextChanged += (s, e) => Bindings.Update();
}
public HomePageViewModel VM => (HomePageViewModel)DataContext;
}
Along with this definition of the page, which adds DataContext="{x:Null}"
:
<Page
x:Class="XBindSampleNet7.Views.Content.Welcome.HomePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XBindSampleNet7.Views.Content.Welcome"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
DataContext="{x:Null}"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
This is enough to get the x:Bind
instances on the page to update properly, without the DataContext
being propagated (DataContextChanged
is only raised once).
It is unlikely that we will be able to find an automated workaround until https://github.com/unoplatform/uno/issues/3519 is fixed. As the Loaded
event happens too early, the only way to react to DataContext
changes, like this sample does, is to observe the DataContexChanged
event, which we cannot detect reliably the uses of in user code.
Thanks for the workaround @jeromelaban. Does it work with the OneTime
mode?