nokola
Topic Author
Posts: 188
Joined: 10 Mar 2015, 05:29

Noesis 2 can't import XAMLs always because it runs code-behind

07 Apr 2017, 07:34

On our other project (non-blank) that we managed to get to work after import/reimport in Unity 5.6 I noticed that the code behind runs on import.
Some of the code accesses textures or resources that are not loaded until runtime. This causes the import to fail and in some cases Unity crash.
Ideally Noesis shouldn't run any user C# code on import.
As a workaround, we either make changes to the C# files that we revert, or we press "Play" then import - effectively importing only works in play mode.

Is there a reason why Noesis would run any C# code when importing XAML files to create .asset files?
Last edited by nokola on 08 Apr 2017, 22:07, edited 1 time in total.
 
User avatar
ai_enabled
Posts: 221
Joined: 18 Jul 2013, 05:28
Contact:

Re: Noesis 2 can't import XAMLs always because it runs code-behind

07 Apr 2017, 07:44

NoesisGUI 2.0 tries to instantiate the XAML control during import to generate the preview (Unity asset preview image). Not really useful and most likely will fail so I'm not really sure why it's enabled by default. You could disable the preview generation in the NoesisGUI settings panel.
Asset-files are basically XAML with another extension, there are no any pre-processing done. NoesisGUI 2.0 could directly load any XAML file, there is no build tool anymore.
AtomicTorch Studio Pte. Ltd. http://atomictorch.com
 
nokola
Topic Author
Posts: 188
Joined: 10 Mar 2015, 05:29

Re: Noesis 2 can't import XAMLs always because it runs code-behind

07 Apr 2017, 07:49

Thanks! I'll try it. Regardless, if the code-behind crashes, the preview should still work.

In my case the code behind doesn't really do anything with the XAML on init, just starts some operations that access resources on init.
If that ends up "scrambling" the preview or having partial preview for the XAML because the code-behind crashed that's OK. Much better than failing to reimport :(
 
User avatar
jsantos
Site Admin
Posts: 2905
Joined: 20 Jan 2012, 17:18
Contact:

Re: Noesis 2 can't import XAMLs always because it runs code-behind

07 Apr 2017, 23:25

When importing a XAML, process that happens each time they are modified, we need to fully load the XAML because:
  • The thumbnail icon is regenerated (this can be disabled as ai_enabled indicated)
  • We provide parsing errors at edit time. We think this is better than doing it when you hit Play.
Fully loading a XAML implies instantiating all the classes inside the tree. Including the code-behind and its constructor. We could avoid instantiating the class indicated in the x:class keyword but I am not sure if that would be correct. In fact, code in the initialization part of the code-behind could affect the render output.

But it is true that it shouldn't be strictly needed just to check syntax errors and edit time... Anyway we have improved this process to behave correctly when the code-behind crashes and we hope to release a new version very soon.
 
nokola
Topic Author
Posts: 188
Joined: 10 Mar 2015, 05:29

Re: Noesis 2 can't import XAMLs always because it runs code-behind

08 Apr 2017, 01:41

Awesome, thanks! Maybe having a bool IsInDesignMode (similar to WPF) can help avoid these. Anyway, if the errors from code behind are reported correctly, it would be easy to add checks "if null then skip part X of the code" etc. Looking forward to the new version :)
 
User avatar
sfernandez
Site Admin
Posts: 1915
Joined: 22 Dec 2011, 19:20

Re: Noesis 2 can't import XAMLs always because it runs code-behind

12 Apr 2017, 12:00

Just to clarify this a bit.

When a XAML is imported to Unity we load it to show all the errors it can contain. This means we create the entire tree of elements associated with that xaml, so the constructor of each element will get called.

If an element happens to be a code-behind class, then its constructor should have a LoadComponent in its constructor, but only that. All the extra initialization code related to that class should go inside Initialized or Loaded event handlers. A code-behind class could look like this:
public class MyControl : UserControl
{
  public MyControl()
  {
    Initialized += MyControl_Initialized;
    Loaded += MyControl_Loaded;
    InitializeComponent();
  }
  
  private void InitializeComponent()
  {
    Noesis.GUI.LoadComponent(this, "path_to_associated_xaml");
  }
  
  private void MyControl_Initialized(object sender, EventArgs e)
  {
    // this is raised when control gets added to NoesisView UI tree
  }
  
  private void MyControl_Loaded(object sender, RoutedEventArgs e)
  {
    // this is raised when control finishes its first layout pass, so everything in
    // the UI tree is already measured and arranged, all templates are applied
  }
}
Code in Initialized or Loaded handlers won't be called until control gets added to a View. The thing is if you have previews enabled in Unity we are in fact creating a View, attaching the xaml content and trying to render a frame, so if your Initialized/Loaded code depends on application being running, it is better to disable the previews.
 
nokola
Topic Author
Posts: 188
Joined: 10 Mar 2015, 05:29

Re: Noesis 2 can't import XAMLs always because it runs code-behind

13 Apr 2017, 02:40

Thanks!

Can Initialized be called more than once? e.g. if I attach, detach, then re-attach control to the UI tree? We do this often since we have screens/pages and navigation and swap in/out controls.
Similarly, does Loaded get called more than once?

We'll likely move all code out of the constructors or disable previews
 
User avatar
sfernandez
Site Admin
Posts: 1915
Joined: 22 Dec 2011, 19:20

Re: Noesis 2 can't import XAMLs always because it runs code-behind

25 Apr 2017, 12:56

Initialized event is called only once, the first time an object is attached to a View.
Otherwise, the Loaded/Unloaded events are called many times, whenever the element is added (Loaded) and removed (Unloaded) from the tree.

Who is online

Users browsing this forum: No registered users and 1 guest