Bind a button to a command (Windows Phone 7.5)

Bart Teunissen picture Bart Teunissen · Aug 30, 2012 · Viewed 7k times · Source

I'm working on my windows-phone app which uses some simple data binding. I've already created a app which was based on the MvvM programming method.The app i'm currently working on also works by MvvM method. Because i want to keep my code behind as clean as possible i was looking for a way to make the "button click event" (which normally takes place in the codebehind page) take place in my viewmodel or mainviewmodel.

I have searched the internet in need of a simple explanation for the Icommand interface because i believe that's the way to go. Problem with the explanations I found was that some of them were based on MvvMlight toolkit using the CommandRelay function. I don't want to use the MvvM light toolkit because I want to understand things myself first. The other tutorials I found were written by over enthusiastic developers which give you an overkill of information.

Can someone show me the Most simple version of an Icommand bound to a button works?

Answer

Jay picture Jay · Aug 30, 2012

In your XAML:

<Button Content="My Button" Command="{Binding MyViewModelCommand}" />

In your view-model:

public class MyViewModel
{

    public MyViewModel()
    {
        MyViewModelCommand = new ActionCommand(DoSomething);
    }

    public ICommand MyViewModelCommand { get; private set; }

    private void DoSomething()
    {
        // no, seriously, do something here
    }
}

INotifyPropertyChanged and other view-model pleasantries elided.
An alternative way to structure the command in your view-model is shown at the bottom of this answer.

Now, you'll need an implementation of ICommand. I suggest starting with something simple like this, and extend or implement other features/commands as necessary:

public class ActionCommand : ICommand
{
    private readonly Action _action;

    public ActionCommand(Action action)
    {
        _action = action;
    }

    public void Execute(object parameter)
    {
        _action();
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;
}

Here is an alternative way to layout your view-model:

public class MyViewModel
{
    private ICommand _myViewModelCommand;
    public ICommand MyViewModelCommand
    {
        get 
        {
            return _myViewModelCommand
                ?? (_myViewModelCommand = new ActionCommand(() => 
                {
                    // your code here
                }));
        }
    }
}