How do I remove dependency on Command and Xamarin.Forms in View-Model when following MVVM pattern?

EasyGoingPatEasyGoingPat GBMember ✭✭✭

Hi,

I have read tons about following the MVVM pattern in Xamarin.Forms. To follow pure MVVM, there seem to be two main problems: (1) how to perform navigation without depending on Navigation (and the dependency on Xamarin.Forms in the View-Model classes); and (2) how to use commands without using the Command type (and again depending on Xamarin.Forms).

I have read lots of solutions for the first problem, but I don't seem to be able to find anything on solving the second problem. It seems to me that I need to implement my own concrete type implementing the ICommand interface, but I can't find any good information on how to do this.

Can anyone point me at some good information on how to do this, or tell me if I am barking up completely the wrong tree?

Kind wishes ~ Patrick

PS - Congratulations to everyone on this forum! It is one of the friendliest, most helpful forums I have ever used in thirty years of programming.

Best Answer

Answers

  • NMackayNMackay GBInsider, University mod

    @EasyGoingPat

    Hi,

    I have a navigation service I register in my IoC that the viewmodels can use to call navigation events. Also I use MVVM Light which has the RelayCommand implementation of ICommand the VM's can use.

    All my models, viewmodels, data services etc live in a separate PCL project and has no reference to Forms to keep a clear SoC, it also allows a degree of code sharing with our WPF apps.

    If you PM me I'll send you a link to a sample project which demonstrates these approaches.

    Cheers.

  • EasyGoingPatEasyGoingPat GBMember ✭✭✭
    edited January 2016

    Hi,

    I have been poking around in MvvmLight, and I have found one thing I simply don't understand. Since I don't really want an entire framework simply to get one command, I thought about implementing my own command based on ICommand.

    MvvmLight does this with its RelayCommand. So, I thought I would be able to follow the same approach. Looking at the implementation of RelayCommand, it makes use of the CommandManager, which is defined in PresentationCore.dll. If I try to include a reference to this directly in my project, it fails to build, complaining that the assembly does not match my target processor. This happens with both the 32-bit and 64-bit versions of the assembly.

    So, my question is: how is MvvmLight managing to make use of this assembly?

    ~ Patrick

  • MichaelRumplerMichaelRumpler ATMember ✭✭✭✭✭

    All the UI components of Xamarin.Forms only make use of ICommand and not of Xamarin.Forms.Command. So you really don't need the reference in your VMs. I found a simple source of a DelegateCommand here.

    I don't understand why Xamarin added the Xamarin.Forms.Command, but didn't make use of it themselves. They could enable/disable buttons on CanExecuteChanged. This would be a useful extension, but they don't do that.
    As it is now, it only encourages users to keep the reference to XF in the VMs.

  • EasyGoingPatEasyGoingPat GBMember ✭✭✭

    Thank you for that, Michael. I have been working from a similar example here. All was going great until I got to the reference to the CommandManager. This won't compile. The only place I can find it is in PresentationCore.dll, but if I add a reference to this then it complains that the assembly doesn't match my target CPU. I got scared at that point and ran away.

    How did you get the CommandManager to be available in your code?

    • Patrick
  • EasyGoingPatEasyGoingPat GBMember ✭✭✭

    @MichaelRumpler said:
    If you use Xamarins approach (implement a method ChangeCanExecute() and rely that the users calls that), then you don't need a CommandManager at all (I don't know what that is).

    I actually just wrote a class implementing ICommand from scratch. It's not hard to do.
    You can also fire up your favourite decompiler, load the Xamarin.Forms.Core.dll and look at the code of Xamarin.Forms.Command and Xamarin.Forms.Command. They are just a few lines without any references and can be copied easily.

    I had to laugh when I read your suggestion to open up the Xamarin.Forms.Command in a decompiler, Michael, because that is exactly what I am in the middle of doing. I'm glad you pointed out the ChangeCanExecute() method though, because that was one detail I had so far overlooked.

    Thank you for your help.

    ~ Patrick

Sign In or Register to comment.