Xamarin.forms: [Bug] An element with the same key already exists in NameScope

Created on 5 Oct 2019  ·  36Comments  ·  Source: xamarin/Xamarin.Forms

Description

Now that issue #7452 is fixed with the latest 4.2 version I receive a new exception:

public partial class TemplateBefund : ContentView

public partial class Endbefund : TemplateBefund

System.ArgumentException: An element with the same key already exists in NameScope
Parameter name: name
at Xamarin.Forms.Internals.NameScope.Xamarin.Forms.Internals.INameScope.RegisterName
in D:\a\1\s\Xamarin.Forms.Core\Internals\NameScope.cs:21
at DemoProject.Endbefund.InitializeComponent ()
at DemoProject.Endbefund..ctor

Basic Information

  • Version with issue: 4.2
  • Last known good version: 4.1
needs-info ❓ unverified bug

Most helpful comment

I tweaked the exception slightly to give me a pointer about where to find the problem:
image

Here is the change:
image

It would be helpful to add more info to the exception, so you know what control is causing a problem with which name and which names have been already registered.

All 36 comments

Can you please attach a small project that demonstrates this issue? Thanks!

I had this problem too. I had many x:Name="Root" setters on the top level element that were being x:Reference'd somewhere else. I ended up assigning more unique names to get around the issue.

@StephaneDelcroix

Here's a repro

App101.zip

I had many x:Name="Root" setters on the top level element

that's a problem.

both the base class and the derived one, being the same instance, share the same Namescope (otherwise you wouldn't be able to FindByName an element)

our advice is "do not inherit xaml views, but use ControlTemplate"

@StephaneDelcroix I don't use the same name several times, this is a definitely a bug!

@mknotzer this definitely require a repro project then.

My bad, found the duplicate names. The ContentViews had the same name.

  • why is there no exception in XF 4.1?
  • is it possible to get the duplicate name with the exception message?

My bad, found the duplicate names. The ContentViews had the same name.

I suspected that ¯_(ツ)_/¯

  • why is there no exception in XF 4.1?

in 4.1, the namescope of the derived view was replacing the one from the parent, and it wasn't possible to access the parent namescope

  • is it possible to get the duplicate name with the exception message?

we replicate what is done with, e.g., Dictionary<,>

I'm having difficulties to isolate the issue in my App. I removed two names in one case and then I was able to launch that page without NameScope exception. However these names were unique in the page. This scenario was made up of a tabbedbar and 3 pages, declared in XAML. Page 3 had two names and caused for some reason the issues.

Case two is a page with 15 named elements, all having a unique name. I was not able to pinpoint which element causes pain. The code runs fine on earlier XF versions.
It would be nice to get a name of the element causing the problem. Now it's InitializeComponent throwing an exception when it loads the XAML.

OK, I was able to solve case two: the form used editors and these are controls. I had a case where the base control was named "holder" and the specialized control used the same name. Removing these names solved the issue with the data entry form. Still it puzzles me why it worked before...

I tweaked the exception slightly to give me a pointer about where to find the problem:
image

Here is the change:
image

It would be helpful to add more info to the exception, so you know what control is causing a problem with which name and which names have been already registered.

I have the same issue. It was fine for 3.6.

It happens when I create a view for a custom ListView. Each view in the list has x:Name="Root".

I don't understand why it happens because they have different name scopes. It's 100% an error. We should have a chance to create two or more instances of the one element with the same name.

Update

I found a source of the error. I used a base class for each cell. The base class contained XAML with the element with the name "Root". Each cell inherited the base class and they had the name "Root" as well. It was a problem. Names in a base class and names in a child class have to be different.

@rotorgames glad you found your issue.

The base and derived XAML inflates to the same object instance. hence they share the same namescope.

Our advice stands: do not inherit from XAML defined objects, but use ControlTemplate instead

I think there is something wrong.

I have modified a xaml file adding some Entries with x:Name... the error appears but I can debug without problem, but when I change the configuration to "Release" and try to recompile the solution, the errror block the compilation.

Closed VS2019, deleted bin and obj, now it works

This issue is also happening here since I last updated the Xamarin package. I always receive multiple errors (with different element names) when building: Position 82:38. An element with the name "residueSelectionHeader" already exists in this NameScope.
Doing a search for the term it only appears in the XAML its declared, and in the CodeBehind where I add GestureRecognizers to it:
image

Note that this error doesn't stop me from running the application, it just polutes the Error List.

I tweaked the exception slightly to give me a pointer about where to find the problem:
image

Here is the change:
image

It would be helpful to add more info to the exception, so you know what control is causing a problem with which name and which names have been already registered.

@theo-albers you should do a PR to Xamarin.Forms to add this! Had the same issue and this helps a lot!

After the latest Visual Studio 16.3.1 update, I don't get this exception during runtime anymore. However I noticed the problem kind of still exists during debugtime. I see red squiggles under named elements when I debug the App on Android, with hot reload enabled and after having modified the XAML during debug. I guess hot reload tries to reload the same XAML in the same context and detects duplicate names.

I removed some names earlier to fix the runtime issues. This was in cases I inherited from a ContentView and the inherited class had an element with a name as well. Now using this control in another ContentView results in NamedScope issues. My example:

  • I have a ValidatingEditor XAML + cs file with a StackLayout and some elements. Toplevel element has a key with name "holder"
  • I have a ValidatingLineEditor XAML + cs file which inherits from ValidatingEditor and adds the actual editor as content. The top level element has a key with name "holder"
  • I have a page where I add several ValidatingLineEditor controls.
  • Now I get the key already exists exception in the page while I didn't get that before... Removing the "holder" names solves that problem.

@Depechie

@theo-albers you should do a PR to Xamarin.Forms to add this! Had the same issue and this helps a lot!

we use the same message as Dictionary does, when an dupe key is found

@theo-albers, @mateuswolkmer: intelisense squiggles while debugging looks like HotReload messages. the current version of HR doesn't work well with forms>4.2, the next release will fix that.

@Depechie

@theo-albers you should do a PR to Xamarin.Forms to add this! Had the same issue and this helps a lot!

we use the same message as Dictionary does, when an dupe key is found

+1 for improving the error msg please.

I tried pushing my local branch in order to create a pull request, but got a 403. One day I might find the energy to sort this out and contribute directly ;-(
@StephaneDelcroix here is a fix for getting more information about a name clash at runtime. I noticed that direct XAML-parsing already throws the correct XAML parse exception with proper details, Xamarin.Forms\Xamarin.Forms.Xaml\RegisterXNamesVisitor.cs:

            catch (ArgumentException ae) {
                if (ae.ParamName != "name")
                    throw ae;
                var xpe = new XamlParseException($"An element with the name \"{(string)node.Value}\" already exists in this NameScope", node);
                if (Context.ExceptionHandler != null) {
                    Context.ExceptionHandler(xpe);
                    return;
                }
                throw xpe;
            }

This is more about the other scenario where you have a Page XAML which includes controls that are standalone classes with XAML.
Xamarin.Forms.zip

I have a similar issue. I have created a Custom Control based on the ContentView. In the XAML for that user control I use the x:Name="myusercontrol" so that referencing properties on the viewmodel in a datatemplate is easier. The error shows up most when i am using XAML Hot Reload to make changes to the XAML. What is the recommended method to access the parent BindingContext from a Datatemplate without using x:Reference ?? If I can do it another way then i can remove the x:Name attributes in the Custom UserControl XAML. Thanks

similar issue.
I'm using LoadFromXaml for dynamically (re)load,
everytime except the first one will report this error,
I have to fallback to the old version 4.1

I am getting same issue.

Severity Code Description Project File Line Suppression State
Error Position 6:9. An element with the name "listContact" already exists in this NameScope D:\Data\Vatan\Learnings\AA Authors\Mosh\HelloWorld\HelloWorld\HelloWorld\ListItemSelection.xaml 6

My Gitrepo:
https://github.com/vatansoni89/MoshXamarinForms/tree/ea5b960c384d285226c02a2dc4583e33e47f0555

I had once the same issue, the problem was that I was calling the InitializeComponent method twice.

Check that, maybe this could be the issue

It also happens when you're debugging the code and change the XAML with hot reload enabled. You will see purple squiggles, until you stop the debug session.

It also happens when you're debugging the code and change the XAML with hot reload enabled. You will see purple squiggles, until you stop the debug session.

Exact same issue for me.

@StephaneDelcroix You mentioned your advice is "do not inherit xaml views, but use ControlTemplate". Is this official recommendation as of v4.x? Can you explains why?

I'm also seeing this issue in XF 4.3.

4.4 is the same, have to roll back to 4.1.
The problem is with release.
Any plans on fixing?

do this before reload:

(view as BindableObject).SetValue(Xamarin.Forms.Internals.NameScope.NameScopeProperty, null);

view is the object you want to reload.

Our advice stands: do not inherit from XAML defined objects, but use ControlTemplate instead

I don't understand this. Literally every single page has this:
public partial class MainPage : ContentPage

Agreed, I would love to understand this better. I'm still not sure what bug was fixed that is now causing this issue. @StephaneDelcroix can you provide some code samples that will help better understand the issue?

In my case the code someone gave me was calling InitializeComponents() from OnAppearing as well (in addition to the constructor), so definitely a bug in the code. However the error was not helpful. I'd rather be told not to call it again (similar to this PR I made: https://github.com/xamarin/Xamarin.Forms/pull/3470). It would have saved me a few hours of troubleshooting.

Not sure why it even worked on 4.2 though.

In my case the code someone gave me was calling InitializeComponents() from OnAppearing as well (in addition to the constructor), so definitely a bug in the code

I'm confused, is this in response to #7452? Or are you saying you hit this bug because some component was calling InitializeComponent twice? The UWP compiler generates code that so that only the first call to InitializeComponent does anything. Any call after that is a no-op.

I'm just trying to understand the implications of the fix for #7452. Do Custom Views not get their own namescope now?

@dotMorten

I don't understand this. Literally every single page has this:
public partial class MainPage : ContentPage

ContentPage has no XAML defined content, this is fine. What we're advising against is

public class BasePage : ContentPage {}
public class LoginPage : BasePage {}

when BasePage is defined in both C# and XAML. It's not wrong, but it's not the best possible or most efficient design

Was this page helpful?
0 / 5 - 0 ratings

Related issues

joseluisct picture joseluisct  ·  3Comments

Stensan picture Stensan  ·  3Comments

deakjahn picture deakjahn  ·  3Comments

rmarinho picture rmarinho  ·  3Comments

AppGrate picture AppGrate  ·  3Comments