Logrus
Topic Author
Posts: 19
Joined: 22 Jul 2015, 12:16

EventArgs to InvokeCommandAction

29 Nov 2020, 12:03

Hi,
How to pass EventArgs from EventTrigger to InvokeCommandAction?

I solved it by changing the NoesisApp::EventTriggerBase code by adding the GetEventArgs method
    Noesis::EventArgs* EventTriggerBase::GetEventArgs() const;
                          
<i:Interaction.Triggers>
	<i:EventTrigger EventName="MouseUp" x:Name="Trigger.Up">
		<i:InvokeCommandAction Command="{Binding OnCommand}" CommandParameter="{Binding ElementName=Trigger.Up}"/>
	</i:EventTrigger>
</i:Interaction.Triggers>
void OnCommand(BaseComponent* param)
{
	if (param && param->GetClassType() == TypeOf<NoesisApp::EventTrigger>())
	{
		auto trigger = (NoesisApp::EventTrigger*)param;
			
		if (Symbol(trigger->GetEventName()) == Symbol("MouseUp")) {
			auto args = (MouseButtonEventArgs*)trigger->GetEventArgs();
		};

		if (Symbol(trigger->GetEventName()) == Symbol("DragBegun")) {
			auto args = (BehaviorDragEventArgs*)trigger->GetEventArgs();
		};
	}
}

Tags:
 
Logrus
Topic Author
Posts: 19
Joined: 22 Jul 2015, 12:16

Re: EventArgs to InvokeCommandAction

29 Nov 2020, 16:04

Improved the solution a bit.
Wrapped EventArgs in a component.
class NS_APP_INTERACTIVITY_API EventTriggerArgsComponent : public Noesis::BaseComponent
{
public:
    Noesis::Symbol  eventName;
    Noesis::EventArgs* args;

    NS_IMPLEMENT_INLINE_REFLECTION_(EventTriggerArgsComponent, Noesis::BaseComponent)
};
If CommandParameter is not specified in InvokeCommandAction, then EventTriggerArgsComponent* is passed by default
<i:Interaction.Triggers>
	<i:EventTrigger EventName="MouseUp">
		<i:InvokeCommandAction Command="{Binding OmCommand}"/>
	</i:EventTrigger>
</i:Interaction.Triggers>
void OnCommand(BaseComponent* param)
{
	if (param && param->GetClassType() == TypeOf<NoesisApp::EventTriggerArgsComponent>())
	{
		auto component = (NoesisApp::EventTriggerArgsComponent*)param;
			
		if (component->eventName == Symbol("MouseUp")) {
			auto args = (MouseButtonEventArgs*)component->args;
		};
	}
}
 
User avatar
sfernandez
Site Admin
Posts: 2058
Joined: 22 Dec 2011, 19:20

Re: EventArgs to InvokeCommandAction

30 Nov 2020, 17:22

Modifying EventTriggerBase seems the easiest way to achieve what you want (although will change behavior compared to WPF). You need to modify EventTriggerBase::OnEvent to receive an EventArgs so you can pass it from each event handler. Then you can just box the pointer to pass it to the invoked actions:
void EventTriggerBase::OnEvent(const Noesis::EventArgs* e)
{
    InvokeActions(Noesis::Boxing::Box(e));
}
And then in InvokeCommandAction, as you said, if CommandParameter is null, then pass the parameter from the Invoke method:
void InvokeCommandAction::Invoke(BaseComponent* param)
{
    if (GetAssociatedObject() != 0)
    {
        Noesis::ICommand* command = ResolveCommand();
        BaseComponent* commandParameter = GetCommandParameter();
        if (commandParameter != nullptr) param = commandParameter;
        if (command != 0 && command->CanExecute(param))
        {
            command->Execute(param);
        }
    }
}
This will allow your view model command to do the following:
void OnCommand(BaseComponent* param)
{
    if (Boxing::CanUnbox<const EventArgs*>(param))
    {
        const EventArgs* e = Boxing::Unbox<const EventArgs*>(param);
        // ...
    }
}
 
Logrus
Topic Author
Posts: 19
Joined: 22 Jul 2015, 12:16

Re: EventArgs to InvokeCommandAction

01 Dec 2020, 10:19

Ok,
thanks
 
User avatar
sfernandez
Site Admin
Posts: 2058
Joined: 22 Dec 2011, 19:20

Re: EventArgs to InvokeCommandAction

03 Dec 2020, 09:31

You're welcome, marking this as solved.

Who is online

Users browsing this forum: No registered users and 1 guest