How to bind a single command to different view models in wpf?

1.2k views Asked by At

I have 2 views and their respective view models. I have a button in both the views. On click of a button I have to execute the same command from both the views.

<Button Command="{Binding SearchTreeCommand}" Content="Next"/>

I have a command interface which is implemented in both the view models. The execute method has to call a PerformSearch function depending on the data context i.e I have a PerformSearch function in both the viewmodels with different implementation. How do I call the particular implementation of PerformSearch from the execute method of the command?

public class SearchTreeCommand : ICommand
{
    private readonly IViewModel m_viewModel;

    public SearchTreeCommand(IViewModel vm)
    {
        m_viewModel = vm;
    }

    event EventHandler ICommand.CanExecuteChanged
    {
        add { }
        remove { }
    }

    public void Execute(object param)
    {
        //how do I call the PerformSearch method here??
    }

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

public interface IViewModel
{

}
2

There are 2 answers

0
toadflakz On BEST ANSWER

Add PerformSearch to the IViewModel interface and call it in Execute().

public void Execute(object param)
{
    m_viewModel.PerformSearch();
}

public interface IViewModel
{
     void PerformSearch();
}

This means that when your ViewModels implements the interface you can provide different implementations to each but the interface is common between the ViewModels for your Command implementation's needs.

0
AlSki On

I think you are confused. You have said that the two SearchTreeCommands have different implementations according to their view models, so the only thing they share is the name, they aren't actually related.

Also you are binding to a property Name on the view model, not to a Type so your SearchTreeCommand class can be whatever you want to call it.

These means you could do something as simple as

//View Models
public class SimpleViewModel
{
  public ICommand SearchTreeCommand {get;set;}
}

//View 1 with a DataContext of new SimpleViewModel { SearchTreeCommand = new FirstImplementationOfSearchTreeCommand() }
<Button Command="{Binding SearchTreeCommand}" Content="Next"/>    

//View 2 with a DataContext = new SimpleViewModel { SearchTreeCommand = new SecondImplementationOfSearchTreeCommand() }
 <Button Command="{Binding SearchTreeCommand}" Content="Next"/>

or if you need more differentiation in your view models

//View 1 with a DataContext of new SimpleViewModel { SearchTreeCommand = new FirstImplementationOfSearchTreeCommand() }
<Button Command="{Binding SearchTreeCommand}" Content="Next"/>    

//View 2 with a DataContext = new ComplicatedViewModel { SearchTreeCommand = new SecondImplementationOfSearchTreeCommand() }
 <Button Command="{Binding SearchTreeCommand}" Content="Next"/>

//View Models

///<remarks>Notice I don't implement from anything shared with the SimpleView, no interface</remarks>
public class ComplicatedViewModel
{
  public ICommand SearchTreeCommand {get;set;}

  //I have other stuff too ;-)
}