canton7 / Stylet

A very lightweight but powerful ViewModel-First MVVM framework for WPF for .NET Framework and .NET Core, inspired by Caliburn.Micro.
MIT License
992 stars 143 forks source link

Does Stylet have a something like a EventArgsConverter equivalent? #25

Closed FutureTD closed 7 years ago

FutureTD commented 7 years ago

First I would like to say excellent library and to keep up the good work!

As for my question, I am currently using a few third party controls from DevExpress, and a few of the controls pass information through the eventargs. I was wondering if there was a way using Stylet to pass eventargs to the ViewModel or better yet a converter that could convert the eventargs to the type I need.

The DevExpress MVVM framework handles it like this:

 <dxmvvm:Interaction.Triggers>
      <dxmvvm:EventToCommand Command="{Binding YOURCOMMAND}"
                            EventName="THEEVENT"
                            EventArgsConverter="{StaticResource YOUREVENTARGSCONVERTER}"
                            PassEventArgsToCommand="true" />
</dxmvvm:Interaction.Triggers>

Caliburn Micro has:

cm:Message.Attach="[Event LeftSwipe] = [LeftSwipe($source, $eventArgs)]"

In which the $eventArgs are passed to the method on your ViewModel, or you can even create your own $keyword to convert the eventargs to another object (Which I would prefer because I do not want to pass eventargs directly to my ViewModel).

I was just wondering if Stylet had a equivalent?

RyanYANG52 commented 7 years ago

Did you read this wiki https://github.com/canton7/Stylet/wiki/Actions :section Events, is this what you looking for?

`

`

I do not think there is an existed eventarg converter, you should wait see what canton7 have to say

canton7 commented 7 years ago

Yep, @RyanYANG52 is spot on. When you use an action with an event, you can grab the source and the event args in a very similar way to your Caliburn.Micro example (but without the ability to convert the EventArgs to another object). There's no concept of an EventArgsConverter.

If you need to convert the EventArgs into another object type, you can do this using attached behaviours.

Something like this (untested) where we're binding to the Clicked event of a Button

public class WhateverBehavior : Behavior<Button>
{
    public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register("Command", typeof(ICommand), typeof(WhateverBehavior ), new PropertyMetadata(null));

    public ICommand Command
    {
        get { return (ICommand)GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }

    public override void OnAttached()
    {
        base.OnAttached();
        this.AssociatedObject.Clicked += this.ButtonClicked;
    }

    public override void OnDetaching()
    {
        base.OnDetaching();
        this.AssociatedObject.Clicked -= this.ButtonClicked;
    }

    private void ButtonClicked(object sender, RoutedEventArgs ea)
    {
        TransformedEventArgs transformedEventArgs = DoSomethingWith(ea);
        this.Command?.Execute(transformedEventArgs);
    }
}

Then in your view:

<Button ....>
    <i:Interaction.Behaviors>
         <my:WhateverBehavior Command="{s:Action MyHandler}"/>
    </i:Interaction.Behaviors>
</Button>

Then in your ViewModel:

public void MyHandler(TransformedEventArgs ea)
{

}
FutureTD commented 7 years ago

thanks, that should work