KeldorKatarn
Topic Author
Posts: 193
Joined: 30 May 2014, 10:26

Noesis erroneously reports dublicate element name

28 Apr 2021, 02:34

I have an issue here with Noesis reporting a duplicate element name where there is none. I'm not sure what causes this but I had this happen before after a XAML was being reloaded.
The specified name only exists once (I only have two XAML files right now so this is pretty easy to confirm)
I had it happen once before but now I cannot get rid of it.
I get this:
[Error] [noesis] Cannot register duplicate name 'IgnoreMe' in this namescope.
NoesisUnity.UnityLog() at /NoesisGUI/Plugins/NoesisUnity.cs:148
146:   case LogLevel.Error:
147:   {
-->148:       Debug.LogError("[noesis] " + message);
149:       break;
150:   }

FrameworkElement.MeasureOverride() at /NoesisGUI/Plugins/API/Proxies/FrameworkElementExtend.cs:45
43:   if (_measureBaseCallback != null)
44:   {
-->45:       _measureBaseCallback(swigCPtr, ref availableSize, ref desiredSize);
46:   }
47:   return desiredSize;

FrameworkElement.CallMeasureOverride() at /NoesisGUI/Plugins/API/Proxies/FrameworkElementExtend.cs:89
87:   {
88:       _measureBaseCallback = callback;
-->89:       Size desiredSize = MeasureOverride(availableSize);
90:       _measureBaseCallback = null;

Extend.FrameworkElementMeasure() at /NoesisGUI/Plugins/API/Core/Extend.cs:1964
1962:   if (element != null)
1963:   {
-->1964:       desiredSize = element.CallMeasureOverride(availableSize, callback);
1965:       if (desiredSize.IsEmpty) desiredSize = new Size(0, 0);
1966:   }

View.SetSize() at /NoesisGUI/Plugins/API/Core/View.cs:57
55:   public void SetSize(int width, int height)
56:   {
-->57:       Noesis_View_SetSize(CPtr, width, height);
58:   }

NoesisView.UpdateSize() at /NoesisGUI/Plugins/NoesisView.cs:857
855:   if (_camera != null)
856:   {
-->857:       _uiView.SetSize(_camera.pixelWidth, _camera.pixelHeight);
858:   }
859:   else if (_texture != null)

NoesisView.ExternalUpdateInternal() at /NoesisGUI/Plugins/NoesisView.cs:900
898:               }
899:   #endif
-->900:               UpdateSize();
901:               UpdateInputs();
902:               NoesisUnity.IME.Update(_uiView);

NoesisView.LateUpdate() at /NoesisGUI/Plugins/NoesisView.cs:875
873:       if (!_enableExternalUpdate)
874:       {
-->875:           ExternalUpdateInternal();
876:       }
877:   }
This MIGHT be caused by be creating DataTemplates for my viewmodels in the code. However IF that's the case this is a bug.
I'm not sure this is the cause, however if I place the View UserControl inside the other one directly,
instead of using a ContentControl bound to the VM using the View as a generated DataTemplate,
then it doesn't report this error.
Apparently Noesis thinks the name is declared twice by A) the name being in the View used in the datatemplate and B) the view simply existing as an asset. The latter shouldn't matter.
Again I'm not sure that this is the cause. (The name btw is just the name of a parent container DockPanel, so nothing inside another template or anything)

As a reminder, this is what that code does:
            var pairs = this.viewModelTypes.Select(
                vmType => new { ViewModelType = vmType, ViewType = GetViewType(vmType) });

            var root = NoesisView.Content;

            foreach (var pair in pairs.Where(pair => pair.ViewModelType != typeof(ShellViewModel)))
            {
                DataTemplateManager.RegisterDataTemplate(pair.ViewModelType, pair.ViewType, root.Resources);
            }
        public static void RegisterDataTemplate(Type viewModelType, Type viewType, ResourceDictionary dictionary)
        {
            var dataTemplate = CreateTemplate(viewModelType, viewType);

#if NOESIS
            dictionary.Add(viewModelType, dataTemplate);
#else
            dictionary.Add(dataTemplate.DataTemplateKey, dataTemplate);
#endif
        }
        private static DataTemplate CreateTemplate(Type viewModelType, Type viewType)
        {
            string xamlTemplate;

            if (viewType != null)
            {
                xamlTemplate = "<DataTemplate\n" +
                               "  xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n" +
                               "  xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n" +
                               $"  xmlns:vm=\"clr-namespace:{viewModelType.Namespace};assembly={viewModelType.Assembly.GetName().Name}\"\n" +
                               $"  xmlns:v=\"clr-namespace:{viewType.Namespace};assembly={viewType.Assembly.GetName().Name}\"\n" +
                               $"  DataType=\"{{x:Type vm:{viewModelType.Name}}}\">\n" +
                               $"    <v:{viewType.Name} />\n" + "</DataTemplate>";
            }
            else
            {
                xamlTemplate = "<DataTemplate\n" +
                               "  xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n" +
                               "  xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n" +
                               $"  xmlns:vm=\"clr-namespace:{viewModelType.Namespace};assembly={viewModelType.Assembly.GetName().Name}\"\n" +
                               $"  DataType=\"{{x:Type vm:{viewModelType.Name}}}\">\n" +
                               "  <Border Background=\"Magenta\">\n" +
                               $"    <TextBlock Margin=\"5\" Foreground=\"White\" FontWeight=\"Bold\" Text=\"Cannot find view for {viewModelType.FullName}.\" />\n" +
                               "  </Border>\n</DataTemplate>";
            }

            var template = (DataTemplate)XamlReader.Parse(xamlTemplate);

            return template;
        }

Tags:
 
KeldorKatarn
Topic Author
Posts: 193
Joined: 30 May 2014, 10:26

Re: Noesis erroneously reports dublicate element name

30 Apr 2021, 08:39

I keep having this problem unfortunately. Everytime I give something a name, NOESIS keeps reporting it as duplicated.
Also for a while now, every time I open Unity, my project complains about XAMLs being missing, until I manually reimport them. Something is going on here. I'd appreciate some help finding out what the issue is here.
 
User avatar
jsantos
Site Admin
Posts: 3122
Joined: 20 Jan 2012, 17:18
Contact:

Re: Noesis erroneously reports dublicate element name

30 Apr 2021, 10:26

I keep having this problem unfortunately. Everytime I give something a name, NOESIS keeps reporting it as duplicated.
Is this happening since you enabled Hot-reloading in our settings panel?
Also for a while now, every time I open Unity, my project complains about XAMLs being missing, until I manually reimport them. Something is going on here. I'd appreciate some help finding out what the issue is here.
Does it happen everytime your close Unity and open it again?
 
KeldorKatarn
Topic Author
Posts: 193
Joined: 30 May 2014, 10:26

Re: Noesis erroneously reports dublicate element name

30 Apr 2021, 10:31

Hot reloading does not seem to be the issue no.
I just upgraded to Unity 2020.3.6f1 and this still happens. So I don't think Unity is to blame.

And yes everytime I open the Editor now and then try to play my scene, I get the error and need to manually reimport my XAML views.
I even deleted my entire Library folder and let Unity reimport everything but that didn't fix it. If I quit and reopen the editor and press play, I get this:
[Error] [noesis] <memory>(7): Xaml not found 'Assets/Scripts/MapEditor/Views/DialogView.xaml'
GUI.LoadComponent() at /NoesisGUI/Plugins/API/Core/NoesisGUI.cs:292
290:   public static void LoadComponent(object component, string filename)
291:   {
-->292:       Noesis_LoadComponent(Extend.GetInstanceHandle(component), filename);
293:   }

DialogView.InitializeComponent() at /Scripts/MapEditor/Views/DialogView.xaml.cs:37
35:           private void InitializeComponent()
36:           {
-->37:               GUI.LoadComponent(this, "Assets/Scripts/MapEditor/Views/DialogView.xaml");
38:           }
39:   #endif

VacuumBreather.Montreal.MapEditor.Views.DialogView..ctor() at /Scripts/MapEditor/Views/DialogView.xaml.cs:27
25:   public DialogView()
26:   {
-->27:       InitializeComponent();
28:   }

Extend.CreateInstance() at /NoesisGUI/Plugins/API/Core/Extend.cs:4697
4695:           info.Type.FullName));
4696:   }
-->4697:   object instance = info.Creator();
4699:   if (isBaseComponent)

GUI.ParseXaml() at /NoesisGUI/Plugins/API/Core/NoesisGUI.cs:261
259:   public static object ParseXaml(string xamlText)
260:   {
-->261:       IntPtr root = Noesis_ParseXaml(xamlText);
262:       return Extend.GetProxy(root, true);
263:   }

XamlReader.Parse() at /NoesisGUI/Plugins/API/Proxies/XamlReader.cs:20
18:   public static class XamlReader {
19:     public static object Parse(string xamlText) {
-->20:       return Noesis.GUI.ParseXaml(xamlText);
21:     }

DataTemplateManager.CreateTemplate() at /Scripts/UI/DataTemplateManager.cs:71
69:   }
-->71:   var template = (DataTemplate)XamlReader.Parse(xamlTemplate);
73:   return template;

DataTemplateManager.RegisterDataTemplate() at /Scripts/UI/DataTemplateManager.cs:32
30:           public static void RegisterDataTemplate(Type viewModelType, Type viewType, ResourceDictionary dictionary)
31:           {
-->32:               var dataTemplate = CreateTemplate(viewModelType, viewType);
34:   #if NOESIS

UserInterfaceInstaller.Start() at /Scripts/MapEditor/Installers/UserInterfaceInstaller.cs:64
62:   foreach (var pair in pairs.Where(pair => pair.ViewModelType != typeof(ShellViewModel)))
63:   {
-->64:       DataTemplateManager.RegisterDataTemplate(pair.ViewModelType, pair.ViewType, root.Resources);
65:   }
Something about this dynamic generation of datatemplates with Views inside causes an issue here apparently. Both with the naming and with finding the xamls.
 
KeldorKatarn
Topic Author
Posts: 193
Joined: 30 May 2014, 10:26

Re: Noesis erroneously reports dublicate element name

30 Apr 2021, 10:34

Is it maybe because right now I'm putting the datatemplates into the Resources of root control instead of the Application resources (which I only will be able to access in the next version)? Is that causing this issue?

I'm putting them into NoesisView.Content.Resources now. Is that an issue?
 
User avatar
sfernandez
Site Admin
Posts: 2220
Joined: 22 Dec 2011, 19:20

Re: Noesis erroneously reports dublicate element name

30 Apr 2021, 10:44

Hi, another question to try reproducing this. The named element is the UserControl of the view itself, right? something like
<UserControl
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="Views.SomeView"
  x:Name="IgnoreMe">...
Or does this happen with any named element inside the view?
 
KeldorKatarn
Topic Author
Posts: 193
Joined: 30 May 2014, 10:26

Re: Noesis erroneously reports dublicate element name

30 Apr 2021, 10:54

No it's not the UserControl. The first time it happened the named element was a DockPanel. Right now it's a TreeView in a File Dialog I made. I need to name that since I want to attach an event hander in code behind.
 
User avatar
jsantos
Site Admin
Posts: 3122
Joined: 20 Jan 2012, 17:18
Contact:

Re: Noesis erroneously reports dublicate element name

30 Apr 2021, 11:10

And yes everytime I open the Editor now and then try to play my scene, I get the error and need to manually reimport my XAML views.
As the rest of assets in Unity, if you want to load a XAML by code you need to put them in a Resources folder (we don't recommend this) or have references to them from your scene. For this you can use our <noesis:Xaml.Dependencies> or just store each .asset you need in a property of a Unity component.

It is working for you when you reimport everything because at reimport time we load each xaml and unity keeps them in memory for a while.

We know this is confusing, and the root of the problem is having a LoadXaml using string in Unity. We are considering removing this in the future. What do you think?
 
KeldorKatarn
Topic Author
Posts: 193
Joined: 30 May 2014, 10:26

Re: Noesis erroneously reports dublicate element name

30 Apr 2021, 11:15

Ah gotcha. I can do that. I should be able to put them into my bootstrapper component.

As for XamlReader taking a string, please keep that. I'm using that to generate placeholder datatemplates like Caliburn. So if a view isn't found, I'm generating a DataTemplate with a magenta background and atextblock saying "View not found for ViewModel XYZ". That way you can work with just your viewmodels and run the application without it crashing. You just get placeholders everywhere where you haven't created the View yet. That is a great workflow with Caliburn.Micro and I'd like to be able to replicate that in Unity.

Ok. I changed it so I reference every NoesisXaml (had to look up what type those assets actually are). That fixes the missing Xaml problem.
However the double name issue remains.
 
User avatar
sfernandez
Site Admin
Posts: 2220
Joined: 22 Dec 2011, 19:20

Re: Noesis erroneously reports dublicate element name

30 Apr 2021, 12:23

Hi, found the source of the problem with the duplicate names. It is a bug (#1994) in the parser when the xaml being loaded has a template in its root.
We will fix it for the next release.

In the meantime you can wrap the DataTemplate in a ResourceDictionary and define it as a resource:
xamlTemplate =      "<ResourceDictionary\n"+
                    "  xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n" +
                    "  xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n" +
                   $"  xmlns:vm=\"clr-namespace:{viewModelType.Namespace};assembly={viewModelType.Assembly.GetName().Name}\"\n" +
                   $"  xmlns:v=\"clr-namespace:{viewType.Namespace};assembly={viewType.Assembly.GetName().Name}\">\n" +
                    "  <DataTemplate x:Key=\"t\"\n" +
                   $"    DataType=\"{{x:Type vm:{viewModelType.Name}}}\">\n" +
                   $"    <v:{viewType.Name} />\n" +
                    "  </DataTemplate>" + 
                    "</ResourceDictionary>";
var dict = (ResourceDictionary)XamlReader.Parse(xamlTemplate);
return (DataTemplate)dict["t"];

Who is online

Users browsing this forum: No registered users and 5 guests