ICommand Interface

KGy SOFT Core Libraries Help
Represents a command, which can be used to create a binding between an event of one or more sources and zero or more target objects. Can be used easily to bind events with targets with any technology.
See the Remarks section for details.

Namespace:  KGySoft.ComponentModel
Assembly:  KGySoft.CoreLibraries (in KGySoft.CoreLibraries.dll) Version: 5.3.0

public interface ICommand

The ICommand type exposes the following members.


Public methodExecute
Executes the command invoked by the specified source for the specified target.
Extension Methods

Public Extension MethodCreateBinding(IDictionaryString, Object, Boolean)Overloaded.
Creates a binding for a command without any sources and targets. At least one source must be added by the ICommandBinding.AddSource method to make the command invokable. Targets can be added by the ICommandBinding.AddTarget method.
(Defined by Command.)
Public Extension MethodCreateBinding(Object, String, Object)Overloaded.
Creates a binding for a command using the specified source, eventName and targets.
(Defined by Command.)
Public Extension MethodCreateBinding(Object, String, IDictionaryString, Object, Object)Overloaded.
Creates a binding for a command using the specified source, eventName and targets as well as the optionally provided initial state of the binding.
(Defined by Command.)

Unlike the System.Windows.Input.ICommand type, this ICommand represents a stateless command so the implementations are best to be accessed via static members. The command states (such as Enabled or any other status) belong to the created binding represented by the ICommandBinding interface and can be accessed by the ICommandBinding.State property, which returns an ICommandState instance.

To implement a command by using a delegate you can also choose one of the four pairs of predefined classes: SimpleCommand/SimpleCommandTParam, TargetedCommandTTarget/TargetedCommandTTarget, TParam, SourceAwareCommandTEventArgs/SourceAwareCommandTEventArgs, TParam and SourceAwareTargetedCommandTEventArgs, TTarget/SourceAwareTargetedCommandTEventArgs, TTarget, TParam depending whether the command is parameterized, targets specific objects and behaves differently based on the source's state or event arguments.

A binding can be created by the Commands.CreateBinding methods or by the CommandBindingsCollection class. When a binding or a collection of bindings are disposed all of the event subscriptions are released, which makes the cleanup really simple.


Tip Tip
  • Try also online.
  • For a more detailed step-by-step guide see the Command Binding section at the Project Site.

The following examples demonstrate how to define different kind of commands:

public static partial class MyCommands
    // A simple command with no target and ignored source: (assumes we have an ExitCode state)
    public static ICommand CloseApplicationCommand =>
        new SimpleCommand(state => Environment.Exit((int)state["ExitCode"])); // or: .Exit(state.AsDynamic.ExitCode)

    // A source aware command, which can access the source object and the triggering event data
    public static ICommand LogMouseCommand =>
        new SourceAwareCommand<MouseEventArgs>(source => Debug.WriteLine($"Mouse coordinates: {source.EventArgs.X}; {source.EventArgs.Y}"));

    // A targeted command (also demonstrates how to change the command state of another command):
    public static ICommand ToggleCommandEnabled =>
        new TargetedCommand<ICommandState>((state, targetState) => targetState.Enabled = !targetState.Enabled);

    // A source aware targeted command:
    public static ICommand ProcessKeysCommand => new SourceAwareTargetedCommand<KeyEventArgs, Control>(OnProcessKeysCommand);

    private static void OnProcessKeysCommand(ICommandSource<KeyEventArgs> source, Control target)
        // do something with target by source.EventArgs

And a binding for a command can be created in an application, with any kind of UI, which uses events, or even without any UI: only event sources are needed.

public class MyView : SomeViewBaseWithEvents // base can be a Window in WPF or a Form in WindowsForms or simply any component with events.
    private ICommandBinding exitBinding;

    private CommandBindingsCollection commandBindings = new CommandBindingsCollection();

    public MyView()
        // ...some initialization of our View...

        // Simplest case: using the CreateBinding extension on ICommand.
        // Below we assume we have a menu item with a Click event.
        // We set also the initial status. By adding the property state updater the
        // states will be applied on the source as properties.
        exitBinding = MyCommands.CloseApplicationCommand.CreateBinding(
            new Dictionary<string, object>
                { "Text", "Exit Application" },
                { "ShortcutKeys", Keys.Alt | Keys.F4 },
                { "ExitCode", 0 },
           .AddSource(menuItemExit, "Click");

        // If we add the created bindings to a CommandBindingsCollection, then all of them can be disposed at once by disposing the collection.

        // We can create a binding by the Add methods of the collection, too:
        // As we added the property state updater to the exitBinding the menuItemExit.Enabled property will reflect the command state.
        var toggleEnabledBinding = commandBindings.Add(MyCommands.ToggleCommandEnabledCommand, buttonToggle, "Click", exitBinding.State);

        // The line above can be written by a more descriptive fluent syntax (and that's how multiple sources can be added):
        var toggleEnabledBinding = commandBindings.Add(MyCommands.ToggleCommandEnabledCommand)
            .AddSource(buttonToggle, nameof(Button.Click))

        // If we set the state of a binding with a property updater it will be applied for all sources (only if a matching property exists):
        exitBinding.State["Text"] = "A new text for the exit command";

        // Or as dynamic:
        toggleEnabledBinding.State.AsDynamic.Text = "A new text for the exit command";

    protected override Dispose(bool disposing)
         // disposing a CommandBindingsCollection will release all of the internal event subscriptions at once
        if (disposing)


Commands can also have parameter, which is evaluated whenever the command is triggered:

// A parameterized and targeted command:
public static ICommand SetBackColorCommand =>
    new TargetedCommand<Control, Color>((target, value) => target.BackColor = value);

// [...]

// The parameter is evaluated only once whenever the command is triggered but SetBackColorCommand
// will be invoked three times (once for each target) with the same parameter value.
    .AddSource(myViewModel, nameof(myViewModel.SeverityChanged)) // whatever source event
    .WithParameter(() => GetSomeColor(myViewModel.Severity)) // specifying a callback to return a parameter value
    .AddTarget(panelInfo) // now multiple targets will be set by the same parameter

See Also