ARPP3
Topic Author
Posts: 15
Joined: 20 Jun 2023, 21:22

InvokeCommandAction not invoking command

18 Jan 2024, 23:51

Hi, I was having issues with InvokeCommandAction in my Unity project, and I believe I've set it up correctly.

I have created a DelegateCommand extension class, exactly as described here. No changes, except for the namespace to match the other extensions I have.

https://github.com/Noesis/Tutorials/blo ... Command.cs

In my code-behind, the relevant section looks like this:
public DelegateCommand Accept { get; private set; }

private void Accept_Pressed(object parameter)
{
    UnityEngine.Debug.Log($"Accept was pressed!");
}

public MyCustomPage()
{
    InitializeComponent();
    Accept = new DelegateCommand(Accept_Pressed);
}
I have validated this command with a Button! And when clicking on it, the button fires the command as expected. Here's the button, and its CommandBinding.
<Button Content="Test Command"
        Command="{Binding Accept, ElementName=PageRoot}"
        FontSize="30" />
The issue is only happening when I try to bind it to an "InvokeCommandAction" inside of a gamepad trigger. I know the trigger works because, I created a fade-in storyboard which plays when it's triggered. Also, it isn't only broken in the gamepad trigger, I also tried a "Loaded" event trigger and it failed to call there as well.
<UserControl.Resources>
  <ResourceDictionary>
    <Storyboard x:Key="Intro">
      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity"
                                     Storyboard.TargetName="Root">
        <EasingDoubleKeyFrame KeyTime="0"
                              Value="0" />
        <EasingDoubleKeyFrame KeyTime="0:0:0.3"
                              Value="1" />
      </DoubleAnimationUsingKeyFrames>
    </Storyboard>
  </ResourceDictionary>
</UserControl.Resources>

<b:Interaction.Triggers>
  <noesis:GamepadTrigger FiredOn="ButtonUp"
                         Button="Accept">
    <b:ControlStoryboardAction Storyboard="{StaticResource Intro}" />
    <b:InvokeCommandAction Command="{Binding Accept, ElementName=PageRoot}" />  <!-- Fails to execute! -->
  </noesis:GamepadTrigger>
<b:Interaction.Triggers>
A few extra details: The name "PageRoot" is my custom UserControl, and the delegate is in the code-behind for this control. This control itself is not the Data Context! And that's why I have the ElementName specified so I bind to the correct one. I did also try moving the DelegateCommand property into the ViewModel that I have set as the DataContext, but unfortunately it didn't work there either. In both situations it seems to bind without any errors or warnings. And I can set some breakpoints in the DelegateCommand. I see it set up correctly in its constructor, but Execute is never called.

Finally, with the noesis GUI.Inspector tool, I was able to see that the InvokeCommandAction was successfully bound to the Accept property. I have no errors or warnings. I have an image of that here but I did anonymize the data context since it has my project name and would have taken some time to refactor. I promise, the function exists in that context 😊
NoesisInspector.png
So to summarize the things I've tried and tests I've done:
  • The button test seems to suggest the DelegateCommand is fine.
  • The animation test shows the trigger works.
  • The Inspector shows that it's bound with the correct path, and there are no errors or warnings about failed bindings.

Is there another rule about getting this to work that I've missed when setting this up?

Also, it's not related to the issue but, I could take this opportunity to mention a few things I noticed in the docs as I was browsing:

In both of these links below, in their respective xaml demo, the <b:Interaction.Triggers> tag is not closed. Also in the GamepadTrigger Class description for the "ActiveOnFocus" property it describes the behaviour with "KeyDown" and "KeyUp" terminology instead of "ButtonDown" and "ButtonUp".

https://www.noesisengine.com/docs/App.I ... igger.html
https://www.noesisengine.com/docs/App.I ... igger.html
 
ARPP3
Topic Author
Posts: 15
Joined: 20 Jun 2023, 21:22

Re: InvokeCommandAction not invoking command

22 Jan 2024, 00:43

I've run into this issue again, this time with an event trigger for selection changed inside of a ListBox.
<b:Interaction.Triggers>
    <b:EventTrigger EventName="SelectionChanged">
        <b:InvokeCommandAction Command="{Binding ListBoxSelectionChanged, ElementName=PageRoot}" />  <!-- Also fails to execute! -->
    </b:EventTrigger>
</b:Interaction.Triggers>
I really believe this has to be user-error on my end.. 😂 But no clue what it could be..

Another detail maybe that's important: The 'b' alias I have is for this schema. Which again, seems to not be an issue when using the triggers themselves, only the InvokeCommandAction seems to be not working for me. And again, it does bind (at least, there are no errors saying it failed to bind)..
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
 
ARPP3
Topic Author
Posts: 15
Joined: 20 Jun 2023, 21:22

Re: InvokeCommandAction not invoking command

22 Jan 2024, 23:44

I guess we can close this soon! As expected it was user error,

Essentially, since the DelegateCommand class from the documentation uses a constructor to set up its action, and so I was most likely overwriting the referenced class by creating a new object after setting the DataContext for my NoesisView. This is why nothing "failed" to bind, since I believe it was bound successfully but this was just bound to the default object and it was overwritten.

Anyway, this is my bad. I realize now I could have also just called OnPropertyChanged for the delegate command after setting it as an alternative to just creating it before setting the DataContext to my ViewModel. I didn't realize it had "changed" necessarily since I thought I'd set it up at the right point in time. But no, I set it up after setting the data context.

Cheers!
 
User avatar
sfernandez
Site Admin
Posts: 2997
Joined: 22 Dec 2011, 19:20

Re: InvokeCommandAction not invoking command

23 Jan 2024, 13:52

Also, it's not related to the issue but, I could take this opportunity to mention a few things I noticed in the docs as I was browsing:

In both of these links below, in their respective xaml demo, the <b:Interaction.Triggers> tag is not closed. Also in the GamepadTrigger Class description for the "ActiveOnFocus" property it describes the behaviour with "KeyDown" and "KeyUp" terminology instead of "ButtonDown" and "ButtonUp".
Thanks for this feedback, we will fix the documentation for the next release.
this was just bound to the default object and it was overwritten
That could explain what happened.
I realize now I could have also just called OnPropertyChanged for the delegate command after setting it as an alternative to just creating it before setting the DataContext to my ViewModel.
Yes, your data context class can implement the INotifyPropertyChanged interface to notify any changes in the properties, and the UI will listen to that event and update accordingly.

I think we can mark this as fixed then.

Who is online

Users browsing this forum: Bing [Bot], DarkDrdaifters and 4 guests