0

I want to use a method which is not in the code behind for the command's Executed event and another for the CanExecute.

I'm using a RoutedCommand and i do NOT want to use a Delegate Command or a Relay Command.

What I got is a Commands class:

public class Commands
{
    static Commands()
    {
        syncCommand = new RoutedUICommand("Sync", "syncCommand", typeof(Commands));
        undoCommand = new RoutedUICommand("Undo", "UndoCommand", typeof(Commands));
    }

    private static MyHandler handler;
    public static MyHandler Handler
    {
        set { handler = value; }
        get { return handler; }
    }

    private static RoutedUICommand syncCommand;
    public static RoutedUICommand SyncCommand
    {
        get
        { return syncCommand; }
    }

    private static void SyncCanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = Handler != null;
    }

    private static void SyncExecute(object sender, ExecutedRoutedEventArgs e)
    {
        Handler.Action();
    }

    private static RoutedUICommand undoCommand;
    public static RoutedUICommand UndoCommand
    {
      get {  return undoCommand; }
    }

    private static void UndoCanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = Handler.WereChangesMade();
    }

    private static void UndoExecute(object sender, ExecutedRoutedEventArgs e)
    {
        Handler.Undo();
    }
}

And in the ViewModel I got the ICommand properties and buttons with the Command property that binds to these properties.

I want to use the above methods as the methods I'll pass to the Command Binding. How do I do it when they're not in the code behind?

CodeMonkey
  • 11,196
  • 30
  • 112
  • 203

2 Answers2

0

You need to add a CommandBinding to one of your UI elements, as the RoutedUICommand needs to tunnel and bubble somewhere to be handled. If all else fails, your MainWindow.

CommandBindings.Add(new CommandBinding(Commands.SyncCommand, Commands.SyncExecute, Commands.SyncCanExecute));

SyncExecute and SyncCanExecute need to be accessible to where this binding is made, so private won't do.

Troels Larsen
  • 4,462
  • 2
  • 34
  • 54
  • How do I do it from the Xaml? – CodeMonkey Jun 27 '14 at 20:17
  • I may be wrong here, but I don't think the x:Static keyword supports methods. The wording on MSDN is: 'References any static by-value code entity'. Source (http://msdn.microsoft.com/en-us/library/ms742135.aspx). I tried: . You're wrangling the MVVM pattern a WPF and bit here. You could always implement the command itself on your View if you're keen on using XAML (and not RelayCommands). – Troels Larsen Jun 27 '14 at 20:33
  • I don't really understand all the fuss about RelayCommands.. RoutedCommands are much better to support several command's sources – CodeMonkey Jun 27 '14 at 20:40
  • RelayCommands allow you to put your logic in the ViewModel, where they can be easily tested. Certain things like Undo should be (and is, by WPF) implemented in the UI, on each control that is able to Undo. But any command doing actual work on the data itself, should be implemented on the ViewModel. So you can either use the normal RoutedCommands, and call through to the ViewModel and implement it there, or just bind commands to the ViewModel directly. RelayCommands can support multiple sources, you just need the right scope of ViewModel (for example, MainWindowViewModel) – Troels Larsen Jun 27 '14 at 20:45
0

Hi i wrote a "sort of" custom CommandBinding, where you can bind your RoutedCommand to a ICommand. (How to bind a RelayCommand(MVVM) to a RoutedCommand? (CommandBinding))

Community
  • 1
  • 1
Henk
  • 750
  • 10
  • 21