how to trigger xaml button from cpp
Hello,
New to noesis and xaml, forgive a possibly noob question.
We have a need to trigger a button from cpp.
There are likely several ways to do it. Currently, done via FindName("somebutton").CommandParameter() and running that command param through the Command that it would have trigged via mouse click.
This is not optimal as it assumes a lot about structure of the xaml. We would really like this to be very disjointed.
Exact use case: a key needs to activate on an screen button, button will not be in focus/selected, button changes depending on what screen/page is visible at the time. ala: several xaml screens/panels need, say, space-bar to "press" a button defined whos behavior should be defined only in xaml.
1) side question: given Noesis::BaseButton, how does one active the click() on it? Fetching CommandParameter and manually running it seems too manual. Can one "activate" the button and let to do what it's supposed to do? (in case it does more then just running commands, recreating entire trigger block seems overkill).
2) main question: a better solution would be to trigger the button via a binding/event. This is to avoid using FindName(""). We'd like this because we want the xaml button to be ultimately responsible for defining the behavior. This button may not be in focus or even focusable. This button may move inside/out of other blocks and may not even exist on some screens/panels/pages.
2a) is there a good example of this in the samples? If not, how does one trigger a button click via event or binding from cpp with no direct reference to BaseButton?
2b) given a binding trigger/activator is possible, is there a way for xaml button to test if it itself is visible and it's parents parents are visible before self activating?
Thank you.
New to noesis and xaml, forgive a possibly noob question.
We have a need to trigger a button from cpp.
There are likely several ways to do it. Currently, done via FindName("somebutton").CommandParameter() and running that command param through the Command that it would have trigged via mouse click.
This is not optimal as it assumes a lot about structure of the xaml. We would really like this to be very disjointed.
Exact use case: a key needs to activate on an screen button, button will not be in focus/selected, button changes depending on what screen/page is visible at the time. ala: several xaml screens/panels need, say, space-bar to "press" a button defined whos behavior should be defined only in xaml.
1) side question: given Noesis::BaseButton, how does one active the click() on it? Fetching CommandParameter and manually running it seems too manual. Can one "activate" the button and let to do what it's supposed to do? (in case it does more then just running commands, recreating entire trigger block seems overkill).
2) main question: a better solution would be to trigger the button via a binding/event. This is to avoid using FindName(""). We'd like this because we want the xaml button to be ultimately responsible for defining the behavior. This button may not be in focus or even focusable. This button may move inside/out of other blocks and may not even exist on some screens/panels/pages.
2a) is there a good example of this in the samples? If not, how does one trigger a button click via event or binding from cpp with no direct reference to BaseButton?
2b) given a binding trigger/activator is possible, is there a way for xaml button to test if it itself is visible and it's parents parents are visible before self activating?
Thank you.
Re: how to trigger xaml button from cpp
Here's an example of how best case might work:
Then in CPP something along the lines of (if one even has to go through mainwindow):
Code: Select all
<Button
Name="GenericSpaceTriggerButton" Style="{StaticResource MenuButtonStyle}"
Command="{Binding Navigate}" CommandParameter="SpaceDoStuff"
Focusable="False"
Text="Press Space To Do Stuff"
>
<i:Interaction.Triggers>
<SomeKindOfTrigger EventOrBindingName="ActivateSpaceDoStuff">
<i:Invoke self activate if visible and parents visible />
</SomeKindOfTrigger>
</i:Interaction.Triggers>
</Button>
Code: Select all
mApplication->GetMainWindow()->SomeKindOfTrigger("ActivateSpaceDoStuff");
-
sfernandez
Site Admin
- Posts: 2991
- Joined:
Re: how to trigger xaml button from cpp
If you want to trigger a command in response of a Key press you can use a KeyTrigger and InvokeCommandAction.
If what you need is to trigger from the view model an event that you can listen in XAML, then you should use the DataEventTrigger:
Is any of this useful in your case?
Code: Select all
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions">
<i:Interaction.Triggers>
<ei:KeyTrigger FiredOn="KeyDown" Key="Space">
<i:InvokeCommandAction Command="{Binding Navigate}" CommandParameter="SpaceDoStuff"/>
</ei:KeyTrigger>
<i:Interaction.Triggers>
...
</UserControl>
Code: Select all
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:noesis="clr-namespace:NoesisGUIExtensions;assembly=Noesis.GUI.Extensions">
<i:Interaction.Triggers>
<noesis:DataEventTrigger Source="{Binding}" EventName="ActivateSpaceDoStuff">
<i:InvokeCommandAction Command="{Binding Navigate}" CommandParameter="SpaceDoStuff"/>
</noesis:DataEventTrigger>
</i:Interaction.Triggers>
...
</UserControl>
Re: how to trigger xaml button from cpp
Hello,
Thank you for the ideas!
This does trigger without focus! For some reason I really being in focus is required for getting keyboard events. Two more questions about it:
1a) I can't seem to find GamepadContext2 in options for the key, it's not part of keys?
1b) it seems to trigger all instances of this button, how does one check for self and parent visibility? (or does self inherit parents' visibility?)
For:
This looks great!
2a) In the DataEventTrigger page has examples to go xaml -> cpp and event is handled in cpp. I'm wondering if there's an example of cpp generating an event, then sending it to xaml ?
2b) if there is a way for cpp to generate an event and sent it xaml, as 1b, this might be triggered for all listeners, I'm wondering if/how I can limit the send even to a specific UserControl/BaseComponent or check for self and parent visibilities again?
Thank you for the ideas!
Code: Select all
<ei:KeyTrigger FiredOn="KeyDown" Key="Space">
1a) I can't seem to find GamepadContext2 in options for the key, it's not part of keys?
1b) it seems to trigger all instances of this button, how does one check for self and parent visibility? (or does self inherit parents' visibility?)
For:
Code: Select all
<noesis:DataEventTrigger Source="{Binding}" EventName="ActivateSpaceDoStuff">
2a) In the DataEventTrigger page has examples to go xaml -> cpp and event is handled in cpp. I'm wondering if there's an example of cpp generating an event, then sending it to xaml ?
2b) if there is a way for cpp to generate an event and sent it xaml, as 1b, this might be triggered for all listeners, I'm wondering if/how I can limit the send even to a specific UserControl/BaseComponent or check for self and parent visibilities again?
Re: how to trigger xaml button from cpp
Ok, so while exploring stuff for 1a/1b found these:
https://www.noesisengine.com/docs/App.I ... igger.html now this totally works via gamepad.
Here's what I have so far, it checks self visibility and and entire stack (or supposed to)
This should work ... but nothing triggers.
***EDIT: triggers all fine, this method works great! (I have continues controller issues , like it doesn't register sometimes)
***EDIT 2: turns out doesn't work that great, if an input field is currently highlighted (say input player name), all the events go to that field. Is there a way to make these focus/highlight agnostic?
I'm still very interested to do to 2, ala "ActivateSpaceDoStuff" as it's probably the best solution for us
https://www.noesisengine.com/docs/App.I ... igger.html now this totally works via gamepad.
Here's what I have so far, it checks self visibility and and entire stack (or supposed to)
Code: Select all
<noesis:GamepadTrigger FiredOn="ButtonDown" Button="Context2">
<i:InvokeCommandAction Command="{Binding Navigate}" CommandParameter=""/>
<i:Interaction.Behaviors>
<ei:ConditionBehavior>
<ei:ConditionalExpression>
<ei:ComparisonCondition LeftOperand="{Binding Path=IsVisible, ElementName=SpaceDoStuff}" Operator="Equal" RightOperand="True"/>
</ei:ConditionalExpression>
</ei:ConditionBehavior>
</i:Interaction.Behaviors>
</noesis:GamepadTrigger>
***EDIT: triggers all fine, this method works great! (I have continues controller issues , like it doesn't register sometimes)
***EDIT 2: turns out doesn't work that great, if an input field is currently highlighted (say input player name), all the events go to that field. Is there a way to make these focus/highlight agnostic?
I'm still very interested to do to 2, ala "ActivateSpaceDoStuff" as it's probably the best solution for us
-
sfernandez
Site Admin
- Posts: 2991
- Joined:
Re: how to trigger xaml button from cpp
As you found, we created GamepadTrigger to expose gamepad buttons. Both KeyTrigger and GamepadTrigger hook by default to the root of the tree to listen to any KeyDown that wasn't handle by any other control. You can add these trigger on a specific control and set the ActiveOnFocus="True" but then the control needs to be focused to trigger, so I guess that won't work for you. You can create your own trigger by inheriting from interactivity TriggerBase/EventTriggerBase and register to PreviewKeyDown to get all the keys before they can be handled, please let me know if you need help to explore this option.
Anyway using DataEventTrigger seems the best option here as you said.
Then in xaml, the DataEventTrigger listens to that event, and performs the actions you need: fire animations, go to a different state, change some property values, even invoke a command (XAML -> C++).
Anyway using DataEventTrigger seems the best option here as you said.
That is exactly what DataEventTrigger is designed for. Your view model (the one bound to the control) exposes in its reflection an event that can be invoked whenever the ViewModel wants (C++ -> XAML).I'm wondering if there's an example of cpp generating an event, then sending it to xaml ?
Code: Select all
struct ViewModel: public BaseComponent
{
...
void OnDownloadFinished()
{
_downloadFinished(this, EventArgs::Empty);
}
EventHandler _downloadFinished;
NS_IMPLEMENT_INLINE_REFLECTION(ViewModel, BaseComponent)
{
NsEvent("DownloadFinished", &ViewModel::_downloadFinished);
}
};
Code: Select all
<Grid
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:noesis="clr-namespace:NoesisGUIExtensions;assembly=Noesis.GUI.Extensions">
<TextBlock Text="Download Finished!" Visibility="Collapsed">
<i:Interaction.Triggers>
<noesis:DataEventTrigger Source="{Binding}" EventName="DownloadFinished">
<ei:ChangePropertyAction PropertyName="Visibility" Value="Visible"/>
</noesis:DataEventTrigger>
</i:Interaction.Triggers>
</TextBlock>
</Grid>
Re: how to trigger xaml button from cpp
My mistake, for some reason I read it as xaml to cpp only, Thank you! This also now works.invoked whenever the ViewModel wants (C++ -> XAML).
-
sfernandez
Site Admin
- Posts: 2991
- Joined:
Re: how to trigger xaml button from cpp
Don't worry, glad to hear it works!
Who is online
Users browsing this forum: Ahrefs [Bot], Bing [Bot], Semrush [Bot] and 67 guests