AndreN
Topic Author
Posts: 11
Joined: 01 Sep 2015, 08:28

How to do hot reloading of XAML files in C#?

06 May 2022, 09:33

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
NoesisLib.GUI.SetXamlProvider(...)
calls the method
RaiseXamlChanged(...)
with an uri, Noesis knows that something has changed on that file and will call
LoadXaml(...)
on that provider with the same uri in order to reload it.

The problem is: it does not happen. The method
RaiseXamlChanged(...)
gets called on the provider (I checked it with the debugger and can clearly see the call). But Noesis is afterwards not calling the
LoadXaml(...)
method on that provider. The provider is directly installed with
NoesisLib.GUI.SetXamlProvider(...)
, 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.
 
User avatar
sfernandez
Site Admin
Posts: 2984
Joined: 22 Dec 2011, 19:20

Re: How to do hot reloading of XAML files in C#?

06 May 2022, 13:13

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.
 
AndreN
Topic Author
Posts: 11
Joined: 01 Sep 2015, 08:28

Re: How to do hot reloading of XAML files in C#?

06 May 2022, 13:58

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é
 
AndreN
Topic Author
Posts: 11
Joined: 01 Sep 2015, 08:28

Re: How to do hot reloading of XAML files in C#?

06 May 2022, 17:21

Unfortunately, I still have issues with the hot-reloading. Now the reloading works, but two things are not working:
  • Every time, the file gets reloaded, I get errors about command binding from buttons:
    (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:
                        <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>
    
    Here for example the "MouseEnter" event is not triggered anymore.
Does anyone has a hint, how those event triggers might be influenced by hot-reloading?
I basically used the Buttons Sample from XamlToy to test it: https://www.noesisengine.com/xamltoy/78 ... 9bc0f43c3f
 
User avatar
sfernandez
Site Admin
Posts: 2984
Joined: 22 Dec 2011, 19:20

Re: How to do hot reloading of XAML files in C#?

12 May 2022, 18:12

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
 
AndreN
Topic Author
Posts: 11
Joined: 01 Sep 2015, 08:28

Re: How to do hot reloading of XAML files in C#?

14 May 2022, 06:50

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é

Who is online

Users browsing this forum: camimamedov, Google [Bot] and 44 guests