Call Command from Code Behind
Preface: Without knowing more about your requirements, it seems like a code smell to execute a command from code-behind upon loading. There has to be a better way, MVVM-wise.
But, if you really need to do it in code behind, something like this would probably work (note: I cannot test this at the moment):
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
// Get the viewmodel from the DataContext
MyViewModel vm = this.DataContext as MyViewModel;
//Call command from viewmodel
if ((vm != null) && (vm.MyCommand.CanExecute(null)))
vm.MyCommand.Execute(null);
}
Again - try to find a better way...
Well, if the DataContext is already set you could cast it and call the command:
var viewModel = (MyViewModel)DataContext;
if (viewModel.MyCommand.CanExecute(null))
viewModel.MyCommand.Execute(null);
(Change parameter as needed)
Try this:
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
//Optional - first test if the DataContext is not a MyViewModel
if( !this.DataContext is MyViewModel) return;
//Optional - check the CanExecute
if( !((MyViewModel) this.DataContext).MyCommand.CanExecute(null) ) return;
//Execute the command
((MyViewModel) this.DataContext).MyCommand.Execute(null)
}
I have a more compact solution that I want to share. Because I often execute commands in my ViewModels, I got tired of writing the same if statement. So I wrote an extension for ICommand interface.
using System.Windows.Input;
namespace SharedViewModels.Helpers
{
public static class ICommandHelper
{
public static bool CheckBeginExecute(this ICommand command)
{
return CheckBeginExecuteCommand(command);
}
public static bool CheckBeginExecuteCommand(ICommand command)
{
var canExecute = false;
lock (command)
{
canExecute = command.CanExecute(null);
if (canExecute)
{
command.Execute(null);
}
}
return canExecute;
}
}
}
And this is how you would execute command in code:
((MyViewModel)DataContext).MyCommand.CheckBeginExecute();
I hope this will speed up your development just a tiny bit more. :)
P.S. Don't forget to include the ICommandHelper's namespace too. (In my case it is SharedViewModels.Helpers)