Best MVVM practice to handle command when view is also needed

ZoliZoli ✭✭✭NLMember ✭✭✭
edited March 14 in Xamarin.Forms

Hi,

It might be not really Xamarin.Forms specific question...

Consider you (try to) use MVVM. You have a view, which does something on a click. Your XAML:

<Frame >
    <Frame.GestureRecognizers>
        <TapGestureRecognizer Command="{Binding Commands[OnClicked]}"/>
    </Frame.GestureRecognizers>
</Frame>

It calls nicely into you VM when you click:

public Dictionary<string, ICommand> Commands { get; protected set; } = ...

private void OnClicked(object obj)
{
    //called
}

Now consider, you want to do something with the View as well when user clicks, like play some nice animation as a feedback of the click.

I know you can give a name in XAML to the Frame, and use CommandParameter="{x:Reference _myFrame} , and the VM will receive the View, and you can do whatever you want, but then where is the V<>VM separation?

What is the best approach to do this?

Tagged:

Best Answers

Answers

  • ZoliZoli ✭✭✭ NLMember ✭✭✭

    @JohnHardman
    Sounds interesting. So VM provides some interface for outside word to add any Commands into its chain Command. And when View.Command is triggered in the VM, this chain will invoke all contained Commands (based on Enabled of each), without knowing who owns the Commands, so V<>VM separation remains. The View can add its Command when creates the VM.

  • ZoliZoli ✭✭✭ NLMember ✭✭✭

    @ClintStLaurent
    Wait, so I can use both event (UI) + command (VM) in the same time?
    You mean this

    <Frame >
        <Frame.GestureRecognizers>
            <TapGestureRecognizer 
            Command="{Binding Commands[OnClicked]}"
            Tapped="OnTapView"/>
        </Frame.GestureRecognizers>
    </Frame>
    

    will call both V.OnTapView and VM.OnClicked when user clicks on the Frame?

  • ZoliZoli ✭✭✭ NLMember ✭✭✭
    edited March 14

    @NMackay
    Another option is to create...

    Thanks, also interesting, so here the VM.Command is executed "manually" in the V.ClickEventHandler.

    A quick and dirty way if to use the Tapgesture Tapped event to do the animation while the command binding will execute the command.

    I just asked the same from @ClintStLaurent , so this also works?
    Hmm, this looks the simplest, and a total disconnection of tasks between V and VM.
    Why is this dirty?

  • ClintStLaurentClintStLaurent ✭✭✭✭✭ USUniversity ✭✭✭✭✭

    @Zoli said:
    @ClintStLaurent
    Wait, so I can use both event (UI) + command (VM) in the same time?

    Yep. Works fine. One doesn't break the other. They are for two different purposes in life. One is logic, one is UI.

  • ZoliZoli ✭✭✭ NLMember ✭✭✭
    edited March 14

    Thank you all, all idea are brilliant, and they have their own best scenario to use.

    For my given question, the event/command looks almost the best. But the uncertain order of execution can be a problem. (imagine a button which will switch on/off play_sound setting (VM.Command), and plays a click sound if you click and sound is on (V.Event) -> this case the order MUST be VM -> V, as if you click to enable sounds, it should click, and if you click to disable sounds, it shouldn't click)

  • NMackayNMackay mod GBInsider, University mod

    @Zoli said:
    @NMackay
    Another option is to create...

    Thanks, also interesting, so here the VM.Command is executed "manually" in the V.ClickEventHandler.

    A quick and dirty way if to use the Tapgesture Tapped event to do the animation while the command binding will execute the command.

    I just asked the same from @ClintStLaurent , so this also works?
    Hmm, this looks the simplest, and a total disconnection of tasks between V and VM.
    Why is this dirty?

    It's not dirty as such, I'm just saying the frame control approach might be better if you wanted to have total control over the execution order but I've used both approaches in the past successfully so whatever works best in your scenario :)

  • JohnHardmanJohnHardman mod GBUniversity mod

    @Zoli - This is one of those things where there are many approaches. Which to choose depends largely on personal preference.

    The one thing I would be cautious about is using TapGestureRecognizers, which I know many people do, but which may be problematic with physical keyboards and accessibility requirements.

Sign In or Register to comment.