How to bind WPF button to a command in ViewModelBase?

kor_ picture kor_ · Sep 14, 2012 · Viewed 204.1k times · Source

I have a view AttributeView that contains all sorts of attributes. There's also a button that when pressed, it should set the default values to the attributes. I also have a ViewModelBase class that is a base class for all ViewModels I have. The problem is I can't seem to get the button bound to the command with WPF.

I've tried this, but it just doesn't do anything:

<Button Command="{Binding DataInitialization}" Content="{x:Static localProperties:Resources.BtnReinitializeData}"></Button>

The command is defined (in the ViewModelBase) like this:

public CommandBase DataInitialization { get; protected set; }

and on application startup a new instance is created for the command:

DataInitialization = new DataInitializationCommand()

However, the WPF binding doesn't seem to "find" the command (pressing the button does nothing). The ViewModel used in the current view is derived from the ViewModelBase. What else I can try (I'm quite new to WPF so this might be a very simple question)?

Answer

yo chauhan picture yo chauhan · Sep 14, 2012
 <Grid >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Button Command="{Binding ClickCommand}" Width="100" Height="100" Content="wefwfwef"/>
</Grid>

the code behind for the window:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewModelBase();
    }
}

The ViewModel:

public class ViewModelBase
{
    private ICommand _clickCommand;
    public ICommand ClickCommand
    {
        get
        {
            return _clickCommand ?? (_clickCommand = new CommandHandler(() => MyAction(), ()=> CanExecute));
        }
    }
     public bool CanExecute
     {
        get
        {
            // check if executing is allowed, i.e., validate, check if a process is running, etc. 
            return true/false;
        }
     }

    public void MyAction()
    {

    }
}

Command Handler:

 public class CommandHandler : ICommand
{
    private Action _action;
    private Func<bool> _canExecute;

    /// <summary>
    /// Creates instance of the command handler
    /// </summary>
    /// <param name="action">Action to be executed by the command</param>
    /// <param name="canExecute">A bolean property to containing current permissions to execute the command</param>
    public CommandHandler(Action action, Func<bool> canExecute)
    {
        _action = action;
        _canExecute = canExecute;
    }

    /// <summary>
    /// Wires CanExecuteChanged event 
    /// </summary>
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    /// <summary>
    /// Forcess checking if execute is allowed
    /// </summary>
    /// <param name="parameter"></param>
    /// <returns></returns>
    public bool CanExecute(object parameter)
    {
        return _canExecute.Invoke();
    }

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

I hope this will give you the idea.