简体   繁体   中英

Custom Commands in wpf

I am working ona WPF application that has a toolbar/menu that will have the use for several custom commands. Probably around 15-20. I have seen documentation on how to create custom commands, but none of them necessarily apply to what I am trying to do.

I am using a controller to handle the business logic in my application, and I am trying to keep my view from doing any logic at all.

What I would like to do is create a directory in my project that holds the custom command classes so that I can decouple them from the controller and the view, but I would still like them to be called from the view such as a normal commmand is.

I have also seen the use of a DelegateCommand class, but am not quite sure if that is the direction I want to head in.

I would like to be able to have an arbitrary custom command class such as the following

public CustomCommand: ICommandd
{
    public bool CanExecute(object parameter)
    {
        //arbitrary logic
    }

    public void Execute(object parameter)
    {

    }
}

The idea is that I would have 10-20 of these, and I want to keep them separate from everything else, and have them be called when needed.

I know that there is a way I can separate my custom commands, but am not quite sure.

I am new to using commands, so I still am trying to get a hold of the concept.

thanks,

The concept is you bind a command to a button and the command drives two properties of this button: "on click" and "enabled" resulting in the interface you posted.

The main reason you want to do commanding is to be able to bind button clicks to actions in your view model.

If you create one custom command which takes an action as constructor parameter you can wire methods from your view model directly to your command.

public class RelayCommand: ICommandd
{
    Action action;
    Func<bool> canExecute;

    public RelayCommand(Action action) : this(action, () => true) {}
    public RelayCommand(Action action, Func<bool> canExecute) 
    { 
        this.action = action; 
        this.canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return canExecute();
    }

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

Usage in your view model would be

public RelayCommand SaveCommand { get; set; }

SaveCommand = new RelayCommand(OnSave);

public void Save()
{
    // save logic...
}

If you want to wire CanExecute, too you can use the second ctor and provide a CanSave Method.

public RelayCommand SaveCommand { get; set; }

SaveCommand = new RelayCommand(OnSave, CanSave);

public void Save()
{
    // save logic...
}

public bool CanSave()
{
    return // ... 
}

As you may noticed I dropped the command parameter in my implementation. This will be sufficient in most cases and saves you extra parameters in your handler methods. For the 10% left I implemented a RelayCommand<T> which takes an Action instead of Action and changes the Execute method to

    public void Execute(object parameter)
    {
        action((T)parameter);
    }

which requires a parameterized handler

SaveCommand = new RelayCommand<SomeType>(OnSave);

public void Save(SomeType toSave)
{
    // save logic using parameter
}

This saves you all casting issues you encounter when using object variables and keeps your view models type safe.

Use RelayCommand , it doesn't require you to create a class for each command, you simply add both methods into the constructor as lambda expressions/delegates.

I use it all around my projects, it is a real time-saver.

我最后通过以下帖子回答了我自己的问题:http://www.codeproject.com/KB/WPF/CentralizingWPFCommands.aspx?display=Print

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM