I experience a crash when Shell
is used and I change a resource defined in App.xaml
. I have 3 pages (FlyoutItem
s) defined in Shell
, each page uses label style defined in App.xaml
. If I navigate to 1st or 2nd page and change the style, crash occurs. Crash doesn't occur when I'm navigated to 3rd (last) page and I change the style.
TextStyle
in App.xaml
and save the file to trigger Hot ReloadNo crash occurring after updating the style.
App crashes with exception:
System.ArgumentException: 'Ambiguous routes matched for: //IMPL_about/IMPL_about/about/ matches found: //IMPL_about/IMPL_about/about,//IMPL_about/IMPL_about/about
Parameter name: uri'
VS bug #1079452
I can confirm I'm seeing this as well, however my exception is different
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'GroupableItemsViewController`1'.
at Foundation.NSObject.get_SuperHandle () [0x00012] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.10.0.17/src/Xamarin.iOS/Foundation/NSObject2.cs:449
at UIKit.UICollectionViewController.get_CollectionView () [0x0002a] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.10.0.17/src/Xamarin.iOS/UICollectionViewController.g.cs:1101
at Xamarin.Forms.Platform.iOS.ItemsViewController`1[TItemsView].RemeasureLayout (Xamarin.Forms.VisualElement formsElement) [0x00076] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\ItemsViewController.cs:316
at Xamarin.Forms.Platform.iOS.ItemsViewController`1[TItemsView].HandleFormsElementMeasureInvalidated (Xamarin.Forms.VisualElement formsElement) [0x00000] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\ItemsViewController.cs:331
at Xamarin.Forms.Platform.iOS.StructuredItemsViewController`1[TItemsView].HandleFormsElementMeasureInvalidated (Xamarin.Forms.VisualElement formsElement) [0x00000] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\StructuredItemsViewController.cs:186
at Xamarin.Forms.Platform.iOS.ItemsViewController`1[TItemsView].OnFormsElementMeasureInvalidated (System.Object sender, System.EventArgs e) [0x0000a] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\ItemsViewController.cs:325
at at (wrapper delegate-invoke) <Module>.invoke_void_object_EventArgs(object,System.EventArgs)
at Xamarin.Forms.VisualElement.InvalidateMeasureInternal (Xamarin.Forms.Internals.InvalidationTrigger trigger) [0x0000b] in D:\a\1\s\Xamarin.Forms.Core\VisualElement.cs:816
at Xamarin.Forms.Grid.InvalidateMeasureInternal (Xamarin.Forms.Internals.InvalidationTrigger trigger) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\Grid.cs:230
at Xamarin.Forms.Layout.OnChildMeasureInvalidated (Xamarin.Forms.VisualElement child, Xamarin.Forms.Internals.InvalidationTrigger trigger) [0x00090] in D:\a\1\s\Xamarin.Forms.Core\Layout.cs:355
at Xamarin.Forms.Layout.OnChildMeasureInvalidated (System.Object sender, System.EventArgs e) [0x00013] in D:\a\1\s\Xamarin.Forms.Core\Layout.cs:212
at Xamarin.Forms.VisualElement.InvalidateMeasureInternal (Xamarin.Forms.Internals.InvalidationTrigger trigger) [0x0000b] in D:\a\1\s\Xamarin.Forms.Core\VisualElement.cs:816
at Xamarin.Forms.VisualElement.OnIsVisibleChanged (System.Boolean oldValue, System.Boolean newValue) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\VisualElement.cs:847
at Xamarin.Forms.Layout.OnIsVisibleChanged (System.Boolean oldValue, System.Boolean newValue) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\Layout.cs:399
at Xamarin.Forms.VisualElement+<>c.<.cctor>b__265_4 (Xamarin.Forms.BindableObject bindable, System.Object oldvalue, System.Object newvalue) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\VisualElement.cs:149
at Xamarin.Forms.BindableObject.SetValueActual (Xamarin.Forms.BindableProperty property, Xamarin.Forms.BindableObject+BindablePropertyContext context, System.Object value, System.Boolean currentlyApplying, Xamarin.Forms.Internals.SetValueFlags attributes, System.Boolean silent) [0x00120] in D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:463
at Xamarin.Forms.BindableObject.SetValueCore (Xamarin.Forms.BindableProperty property, System.Object value, Xamarin.Forms.Internals.SetValueFlags attributes, Xamarin.Forms.BindableObject+SetValuePrivateFlags privateAttributes) [0x00173] in D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:397
at Xamarin.Forms.BindingExpression.ApplyCore (System.Object sourceObject, Xamarin.Forms.BindableObject target, Xamarin.Forms.BindableProperty property, System.Boolean fromTarget) [0x00220] in D:\a\1\s\Xamarin.Forms.Core\BindingExpression.cs:156
at Xamarin.Forms.BindingExpression.Apply (System.Object sourceObject, Xamarin.Forms.BindableObject target, Xamarin.Forms.BindableProperty property) [0x0006b] in D:\a\1\s\Xamarin.Forms.Core\BindingExpression.cs:71
at Xamarin.Forms.Binding.Apply (System.Object context, Xamarin.Forms.BindableObject bindObj, Xamarin.Forms.BindableProperty targetProperty, System.Boolean fromBindingContextChanged) [0x0006d] in D:\a\1\s\Xamarin.Forms.Core\Binding.cs:136
at Xamarin.Forms.BindableObject.ApplyBindings (System.Boolean skipBindingContext, System.Boolean fromBindingContextChanged) [0x00041] in D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:480
at Xamarin.Forms.BindableObject.SetInheritedBindingContext (Xamarin.Forms.BindableObject bindable, System.Object value) [0x0005a] in D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:209
at Xamarin.Forms.Element.SetChildInheritedBindingContext (Xamarin.Forms.Element child, System.Object context) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\Element.cs:505
at Xamarin.Forms.Element.<OnBindingContextChanged>b__82_0 (Xamarin.Forms.BindableObject child, System.Object bc) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\Element.cs:308
at Xamarin.Forms.BindableObjectExtensions.PropagateBindingContext[T] (Xamarin.Forms.BindableObject self, System.Collections.Generic.IList`1[T] children, System.Action`2[T1,T2] setChildBindingContext) [0x0002c] in D:\a\1\s\Xamarin.Forms.Core\BindableObjectExtensions.cs:28
at Xamarin.Forms.Element.OnBindingContextChanged () [0x00000] in D:\a\1\s\Xamarin.Forms.Core\Element.cs:306
at Xamarin.Forms.View.OnBindingContextChanged () [0x0000c] in D:\a\1\s\Xamarin.Forms.Core\View.cs:158
at Xamarin.Forms.Grid.OnBindingContextChanged () [0x00006] in D:\a\1\s\Xamarin.Forms.Core\Grid.cs:147
at Xamarin.Forms.BindableObject.SetInheritedBindingContext (Xamarin.Forms.BindableObject bindable, System.Object value) [0x00062] in D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:210
at Xamarin.Forms.Element.SetChildInheritedBindingContext (Xamarin.Forms.Element child, System.Object context) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\Element.cs:505
at Xamarin.Forms.Element.<OnBindingContextChanged>b__82_0 (Xamarin.Forms.BindableObject child, System.Object bc) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\Element.cs:308
at Xamarin.Forms.BindableObjectExtensions.PropagateBindingContext[T] (Xamarin.Forms.BindableObject self, System.Collections.Generic.IList`1[T] children, System.Action`2[T1,T2] setChildBindingContext) [0x0002c] in D:\a\1\s\Xamarin.Forms.Core\BindableObjectExtensions.cs:28
at Xamarin.Forms.Element.OnBindingContextChanged () [0x00000] in D:\a\1\s\Xamarin.Forms.Core\Element.cs:306
at Xamarin.Forms.View.OnBindingContextChanged () [0x0000c] in D:\a\1\s\Xamarin.Forms.Core\View.cs:158
at Xamarin.Forms.BindableObject.SetInheritedBindingContext (Xamarin.Forms.BindableObject bindable, System.Object value) [0x00062] in D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:210
at Xamarin.Forms.Element.SetChildInheritedBindingContext (Xamarin.Forms.Element child, System.Object context) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\Element.cs:505
at Xamarin.Forms.Element.<OnBindingContextChanged>b__82_0 (Xamarin.Forms.BindableObject child, System.Object bc) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\Element.cs:308
at Xamarin.Forms.BindableObjectExtensions.PropagateBindingContext[T] (Xamarin.Forms.BindableObject self, System.Collections.Generic.IList`1[T] children, System.Action`2[T1,T2] setChildBindingContext) [0x0002c] in D:\a\1\s\Xamarin.Forms.Core\BindableObjectExtensions.cs:28
at Xamarin.Forms.Element.OnBindingContextChanged () [0x00000] in D:\a\1\s\Xamarin.Forms.Core\Element.cs:306
at Xamarin.Forms.View.OnBindingContextChanged () [0x0000c] in D:\a\1\s\Xamarin.Forms.Core\View.cs:158
at Xamarin.Forms.Grid.OnBindingContextChanged () [0x00006] in D:\a\1\s\Xamarin.Forms.Core\Grid.cs:147
at Xamarin.Forms.BindableObject.SetInheritedBindingContext (Xamarin.Forms.BindableObject bindable, System.Object value) [0x00062] in D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:210
at Xamarin.Forms.Element.set_Parent (Xamarin.Forms.Element value) [0x000dc] in D:\a\1\s\Xamarin.Forms.Core\Element.cs:201
at Xamarin.Forms.Element.OnChildRemoved (Xamarin.Forms.Element child) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\Element.cs:335
at Xamarin.Forms.VisualElement.OnChildRemoved (Xamarin.Forms.Element child) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\VisualElement.cs:750
at Xamarin.Forms.Layout.OnInternalRemoved (Xamarin.Forms.View view) [0x00012] in D:\a\1\s\Xamarin.Forms.Core\Layout.cs:473
at Xamarin.Forms.Layout.InternalChildrenOnCollectionChanged (System.Object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) [0x0002b] in D:\a\1\s\Xamarin.Forms.Core\Layout.cs:436
at System.Collections.ObjectModel.ObservableCollection`1[T].OnCollectionChanged (System.Collections.Specialized.NotifyCollectionChangedEventArgs e) [0x00018] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.ObjectModel/src/System/Collections/ObjectModel/ObservableCollection.cs:263
at System.Collections.ObjectModel.ObservableCollection`1[T].OnCollectionChanged (System.Collections.Specialized.NotifyCollectionChangedAction action, System.Object item, System.Int32 index) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.ObjectModel/src/System/Collections/ObjectModel/ObservableCollection.cs:338
at System.Collections.ObjectModel.ObservableCollection`1[T].RemoveItem (System.Int32 index) [0x00021] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.ObjectModel/src/System/Collections/ObjectModel/ObservableCollection.cs:182
at System.Collections.ObjectModel.Collection`1[T].Remove (T item) [0x00027] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/Common/src/CoreLib/System/Collections/ObjectModel/Collection.cs:128
at Xamarin.Forms.ContentPresenter.OnContentChanged (Xamarin.Forms.BindableObject bindable, System.Object oldValue, System.Object newValue) [0x00034] in D:\a\1\s\Xamarin.Forms.Core\ContentPresenter.cs:82
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021
at Foundation.NSAsyncSynchronizationContextDispatcher.Apply () [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.10.0.17/src/Xamarin.iOS/Foundation/NSAction.cs:178
at at (wrapper managed-to-native) UIKit.UIApplication.UIApplicationMain(int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.10.0.17/src/Xamarin.iOS/UIKit/UIApplication.cs:86
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0000e] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.10.0.17/src/Xamarin.iOS/UIKit/UIApplication.cs:65
at MyApp.Mobile.Field.iOS.Application.Main (System.String[] args) [0x00001] in /Users/chaseflorell/Projects/MyApp/MyApp.Mobile.Field/MyApp.Mobile.Field.iOS/Main.cs:12
This issue also occurs when any of my pages includes resource dictionary from file (via MergedDictionaries). If Settings page includes SomeResources.xaml and I change a resource in SomeResources.xaml, I get the same crash.
Thus, the only workaround is having all resources declared in all pages.
Can somebody take a look at this issue?
@viktorszekeress good call on the Merged Dictionaries, I've got that too when I see the crash.
<?xml version="1.0" encoding="UTF-8"?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
...>
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<xaml:Colors />
<xaml:GlobalStyles />
<xaml:TemplateStyles />
<xaml:Fonts />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
This is a problem with hot reload. Routes are registered twice when the shell XAML file is edited. After restarting the app everything is normal.
Xamarin Forms 4.5
Hey folks, Hot Reload dev here 馃憢
@GuidoNeele @viktorszekeress
The issue you're seeing here is, as far as I can tell, is directly to do with Shell itself being invoked via Hot Reload. The resource dictionaries, however they're set up, don't matter since the Shell routes are being reinvoked, causing the Ambiguous routes matched for
error to be thrown. You can invoke the same error editing any of the lines inside of the AppShell.xaml
too, and you can reproduce this in the Xaminals shell sample.
Generally, in the current implementation of XAML Hot Reload, when you make a change to the App.xaml
, we only invoke XamlLoader.LoadResources, which replaces the loaded resources in your app. For other changes (RDs, ContentPages, etc), it uses XamlLoader.Load
In the case of a Shell app, if you touch elements that end up poking at the AppShell
, it ends up reloading the AppShell
, which then causes the routes to be reapplied, causing the error you see.
Now, we (Hot Reload) are working on more enhance editing of changes that could avoid the issue you see here (since you're not changing anything directly in Shell, it shouldn't be trying to reinvoke the routes). However, the underlying issue in Forms still exists. If you actually _were_ trying to edit the routes on your page, the code handling routes would be reapplied, causing the bug to appear again.
@ChaseFlorell The issue you're seeing is unrelated to this one: From what I can tell, there seems to be a bug with how Xamarin.Forms handles the virtualization of the CollectionView, hence it poking elements that are disposed of. Again, this feels more like an issue invoked via Hot Reload, but not something that can solely be fixed _within_ Hot Reload. I would file that separately if it's not already.
Hi @drasticactions, thanks for comprehensive explanation!
From my understanding:
You are now working on fix that will solve the issue when changing resources in App.xaml crashes the app, by avoiding re-invoking the routes in Shell.xaml.
What about the case when I change resources in Shell.xaml? I don't have such scenario with my app, but I can imagine other devs might have it.
Another question - how about my case about merged dictionaries (referenced in pages as MergedDictionaries), fits in the bug description? Does changing resources in dictionary referenced as MergedDictionary invoke routes as well?
@viktorszekeress
TL;DR The actual bug is with Xamarin.Forms Shell not being able to handle reapplying Shell routes. It's invoked via Hot Reload, but the underlying issue is with Forms, so there's nothing for me to fix.
I _am_ working on more incremental ways of editing the XAML Resources that may sidestep bugs like this one, but the actual underlying bug (Reapplying routes on reloads) needs to be addressed.
The issue here, as far as I can tell, is specific to using Xamarin.Forms shell and having assets that end up touching AppShell
, causing it to reapply routes. The other issues you noted (Crashing when editing App.xaml, Merged Dictionaries) are _all related_ to this underlying Shell issue: If you're seeing Ambiguous routes matched for
being thrown on a change, that is this bug, no matter what it's coming from, since it's calling the same code to reapply the routes.
If you try to replicate it in a non-shell app, they (should) work fine. It's because this is a Shell app that's causing this issue. If you can reproduce that in a _non-shell_ app, then that's something else for me to check out.
The Forms code, as far as I can see, only assumes that the routes will be set once, and never again. That, I believe, needs to be changed so that it can be altered and updated if a user does a Hot Reload.
That clears thing up. Thanks!
This is fixed on the latest version of Forms
I tested the original reproduction and it works fine when updated to XF 4.6
Most helpful comment
@viktorszekeress
TL;DR The actual bug is with Xamarin.Forms Shell not being able to handle reapplying Shell routes. It's invoked via Hot Reload, but the underlying issue is with Forms, so there's nothing for me to fix.
I _am_ working on more incremental ways of editing the XAML Resources that may sidestep bugs like this one, but the actual underlying bug (Reapplying routes on reloads) needs to be addressed.
The issue here, as far as I can tell, is specific to using Xamarin.Forms shell and having assets that end up touching
AppShell
, causing it to reapply routes. The other issues you noted (Crashing when editing App.xaml, Merged Dictionaries) are _all related_ to this underlying Shell issue: If you're seeingAmbiguous routes matched for
being thrown on a change, that is this bug, no matter what it's coming from, since it's calling the same code to reapply the routes.If you try to replicate it in a non-shell app, they (should) work fine. It's because this is a Shell app that's causing this issue. If you can reproduce that in a _non-shell_ app, then that's something else for me to check out.
The Forms code, as far as I can see, only assumes that the routes will be set once, and never again. That, I believe, needs to be changed so that it can be altered and updated if a user does a Hot Reload.