I'm developing my first WPF app for university using MVVM. I cannot get this specific binding to work, although i've followed the steps used previously that have been successful.
I have the following xaml snippet:
<Button Command="{Binding GetTicketsCommand}" Canvas.Left="50" Canvas.Top="202" Content="Refresh List" Height="25" Width="137" />
The view initialises the VM as such:
public JobListView()
{
InitializeComponent();
viewModel = new JobListViewModel(this);
this.DataContext = viewModel;
}
The viewmodel has the command called GetTicketsCommand which the button binds to, but when I click the button the command Execute or CanExecute methods do not get called. The command that I created is getting instantiated in the VM constructor.
Any ideas?
Edit:
The command class is like this:
public class GetTicketsCommand : ICommand
{
private readonly JobListViewModel viewModel;
public GetTicketsCommand(JobListViewModel viewModel)
{
this.viewModel = viewModel;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
viewModel.GetTickets();
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
}
And in the viewmodel I simply create an instance of it in the constructor:
public JobListViewModel()
{
GetTicketsCommand = new GetTicketsCommand(this);
dataAccess = new DataLayerClient();
}
Bindings only work with properties. Make sure that your GetTicketsCommand command within your view model is a property:
public ICommand GetTicketsCommand { get; set; }
rather than a field:
public ICommand GetTicketsCommand;
For MVVM scenarios a RelayCommand or DelegateCommand is a better fit than the RoutedCommand which is provided with WPF.
The DelegateCommand is provided in the Prism framework, and see http://msdn.microsoft.com/en-us/magazine/dd419663.aspx for more details for an implementation of a RelayCommand (based on the DelegateCommand).
Commanding has limitations though. For example, a button would be disabled if the command states that it can't execute. What if you wanted to hide the button instead? Commands limit your scope in reimagining the UI.
You might want to look at Caliburn.Micro which implements Actions. These let you invoke verbs on your view model from default events of the control type, all based on conventions.
As an example, if you had a button on your view with a name of Save, then the Save method on your view model will be invoked when the button is clicked. No explicit plumbing is required. You then have further flexibility in the behaviour of the button if the CanSave property on your view model returns false.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With