How to do hot reloading of XAML files in C#?
Hello
I'm currently try to implement hot-reloading for XAML files on C#. The theory sounds very easy, as far as I understand it:
When the XamlProvider, which is set by calls the method with an uri, Noesis knows that something has changed on that file and will call on that provider with the same uri in order to reload it.
The problem is: it does not happen. The method gets called on the provider (I checked it with the debugger and can clearly see the call). But Noesis is afterwards not calling the method on that provider. The provider is directly installed with , so it is not "decorated" by the EmbeddedXamlProvider.
Is there anything further necessary to make hot-relaoding? Do I have to set any global flag or something like that?
I'm using Noesis GUI 3.1.4.
Edit: I also checked, who subscribed to the XamlChanged event of the provider and there is nobody. I don't know, if this is normal or maybe the reason.
I'm currently try to implement hot-reloading for XAML files on C#. The theory sounds very easy, as far as I understand it:
When the XamlProvider, which is set by
Code: Select all
NoesisLib.GUI.SetXamlProvider(...)
Code: Select all
RaiseXamlChanged(...)
Code: Select all
LoadXaml(...)
The problem is: it does not happen. The method
Code: Select all
RaiseXamlChanged(...)
Code: Select all
LoadXaml(...)
Code: Select all
NoesisLib.GUI.SetXamlProvider(...)
Is there anything further necessary to make hot-relaoding? Do I have to set any global flag or something like that?
I'm using Noesis GUI 3.1.4.
Edit: I also checked, who subscribed to the XamlChanged event of the provider and there is nobody. I don't know, if this is normal or maybe the reason.
-
sfernandez
Site Admin
- Posts: 2984
- Joined:
Re: How to do hot reloading of XAML files in C#?
Hi,
The hot reload works only for xamls that are currently added to the visual tree, is that your case?
The RaiseXamlChanged() function calls into our unmanaged code and our library is listening to that to reload the specified xaml. The XamlChanged event in C# is only used when chaining several providers in C# to be able to transfer that event to the final provider set in Noesis. If you are directly setting your provider in Noesis it won't be used.
The hot reload works only for xamls that are currently added to the visual tree, is that your case?
The RaiseXamlChanged() function calls into our unmanaged code and our library is listening to that to reload the specified xaml. The XamlChanged event in C# is only used when chaining several providers in C# to be able to transfer that event to the final provider set in Noesis. If you are directly setting your provider in Noesis it won't be used.
Re: How to do hot reloading of XAML files in C#?
Hi sfernandez
Thanks a lot, with your explanation I found the reason: My provider gave the full path (base path + filename) to the RaiseXamlChanged(...) method instead of only the filename. During testing, I was aware, that this is an error and was still expecting a call to LoadXaml(...), where I wanted to filter the full path accordingly. I did not thought about, that Noesis is only updating files, which it already knows (and which are in the visual tree).
After deleting the base path from the full path before calling RaiseXamlChanged(...) it works now. Thanks!
Maybe this is something you can add to your documentation about resource providers, that the uri, which you use for RaiseXamlChanged(...) must be exactly the same, which have been used before with LoadXaml(...) and that the content of this file must be in the current visual tree.
Best regards
André
Thanks a lot, with your explanation I found the reason: My provider gave the full path (base path + filename) to the RaiseXamlChanged(...) method instead of only the filename. During testing, I was aware, that this is an error and was still expecting a call to LoadXaml(...), where I wanted to filter the full path accordingly. I did not thought about, that Noesis is only updating files, which it already knows (and which are in the visual tree).
After deleting the base path from the full path before calling RaiseXamlChanged(...) it works now. Thanks!
Maybe this is something you can add to your documentation about resource providers, that the uri, which you use for RaiseXamlChanged(...) must be exactly the same, which have been used before with LoadXaml(...) and that the content of this file must be in the current visual tree.
Best regards
André
Re: How to do hot reloading of XAML files in C#?
Unfortunately, I still have issues with the hot-reloading. Now the reloading works, but two things are not working:
I basically used the Buttons Sample from XamlToy to test it: https://www.noesisengine.com/xamltoy/78 ... 9bc0f43c3f
- Every time, the file gets reloaded, I get errors about command binding from buttons:
Code: Select all
(Binding) Binding failed: Path=StartCommand, Source=null(''), Target=Button('StartButton'), TargetProperty=ButtonBase.Command
However the binding still works, so when I press the button, the delegate, which is connect to it, is called. Also the DataContext is not changed, the DataContext is defined in the
parent element of the reloaded xaml file. So, this is maybe just an annoying output, which does not lead to issues. - More problematic is, that certain event trigger do not work anymore:
Here for example the "MouseEnter" event is not triggered anymore.Code: Select all
<Button x:Name="ExitButton" Grid.Row="3" Content="Exit" Margin="60,0,0,0" RenderTransformOrigin="0.5,0.5" Command="{Binding ExitCommand}" > <i:Interaction.Triggers> <i:EventTrigger EventName="MouseEnter"> <noesis:SetFocusAction /> </i:EventTrigger> </i:Interaction.Triggers> <Button.RenderTransform> <TransformGroup> <ScaleTransform /> <SkewTransform /> <RotateTransform /> <TranslateTransform /> </TransformGroup> </Button.RenderTransform> </Button>
I basically used the Buttons Sample from XamlToy to test it: https://www.noesisengine.com/xamltoy/78 ... 9bc0f43c3f
-
sfernandez
Site Admin
- Posts: 2984
- Joined:
Re: How to do hot reloading of XAML files in C#?
1. What LogLevel are these messages from the bindings? In Noesis application framework (as Blend does for WPF) we filter out binding "Info" messages and only show Warnings and Errors: https://github.com/Noesis/Managed/blob/ ... #L361-L362. You should do the same unless you need all the verbosity to debug binding issues.
2. This is a bug that seems related to named elements in the xaml because if I remove the x:Name from the Button then the triggers work fine after the reload. I created a ticket in our bugtracker to fix it: #2348
2. This is a bug that seems related to named elements in the xaml because if I remove the x:Name from the Button then the triggers work fine after the reload. I created a ticket in our bugtracker to fix it: #2348
Re: How to do hot reloading of XAML files in C#?
Hi sferandez
Thanks for looking into this.
The messages have "Debug" level. So yes, they are filtered out by the application framework. Which means, I also can ignore them. Thanks for confirming.
And I can also confirm, that the error with the missing interaction triggers after reloading disappears, when the element does not have names given by x:Name. This is also great, because I normally don't need those names. Thank you also for creating the ticket about this error. I will subscribe to it.
Best regards
André
Thanks for looking into this.
The messages have "Debug" level. So yes, they are filtered out by the application framework. Which means, I also can ignore them. Thanks for confirming.
And I can also confirm, that the error with the missing interaction triggers after reloading disappears, when the element does not have names given by x:Name. This is also great, because I normally don't need those names. Thank you also for creating the ticket about this error. I will subscribe to it.
Best regards
André
Who is online
Users browsing this forum: camimamedov, Google [Bot] and 44 guests