Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Command to call method from viewmodel

OK, I tend to avoid using commands because they always manage to confuse the hell out of me, but I'm on a new project and am trying to architect it correctly with no code behind on my view. Basically All I am trying to do right now is wire up a button that fires a command that does some things on my view model, and somehow something so simple is still giving me trouble. I think I'm close but can't quite get there. Here is what I have right now.

<Window.Resources>
    <RoutedUICommand x:Key="GetMusic" />
</Window.Resources>
<Window.DataContext>
    <core:ViewMain />
</Window.DataContext>
<Window.CommandBindings>
    <CommandBinding Command="{StaticResource GetMusic}" Executed="GetMusicExecuted"/>
</Window.CommandBindings>

And the view model is pretty much nothing right now

public class ViewMain
{
    public MusicCollection Music { get; set; }

    private void GetMusicExecuted(object sender, ExecutedRoutedEventArgs e)
    {
        //Logic
    }
}

Now what I'm trying to do is wire up this command I set up in my command bindings to just call my executed method in my view model, however it tries to find that method within view itself. Is there a way I can direct it to the method in my view model instead, or a better way to set this up to accomplish the same thing? Hoping to keep it simple at first so I don't blow my mind too early.

like image 618
Kevin DiTraglia Avatar asked Jun 16 '12 02:06

Kevin DiTraglia


1 Answers

I tend to use my own command class, implementing ICommand. Then I bind the Button Command property to the command property in my view model. When the button is clicked, it executes the Execute method whatever is bound to the Command property.

This is the ugly two minute version, but it shows how you can make a Command class and then assign it delegates that point back to whatever method you like on your view model.

The ViewModel:

public class MyViewModel
{
    public MyCommand ActionCommand
    {
        get;
        set;
    }

    public MyViewModel()
    {
        ActionCommand = new MyCommand();
        ActionCommand.CanExecuteFunc = obj => true;
        ActionCommand.ExecuteFunc = MyActionFunc;
    }

    public void MyActionFunc(object parameter)
    {
        // Do stuff here 
    }

}

public class MyCommand : ICommand 
{
    public Predicate<object> CanExecuteFunc
    {
        get;
        set;
    }

    public Action<object> ExecuteFunc
    {
        get;
        set;
    }

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

    public event EventHandler CanExecuteChanged;

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

The View would bind to it thusly (assuming DataContext is set to an instance of the view model):

<Window x:Class="exp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button Command="{Binding Path=ActionCommand}">Action</Button>
    </Grid>
</Window>
like image 84
Japple Avatar answered Sep 26 '22 00:09

Japple