Declaring Custom WPF Commands via MarkupExtensions
And yet another markup extension that hopefully makes things a little easier for you. Basically, it’s the same pattern that the good doctor described here for value converters, but with custom commands in mind.
Without Extension
Basically, this extension makes your commands immediately available without having to declare them. One "traditional" way to declare a command is directly in XAML:
<Window.Resources> <cmd:HelloWorldCommand x:Key="SayHello" /> </Window.Resources>
…and then apply it like this:
<Button Command="{StaticResource SayHello}" />
Using the Markup Extension
The declaration part above can become somewhat tedious, especially if you have quite a few commands (e.g. because you are using a ribbon with lots of buttons on it). Thanks to using a markup extension, you can skip the declaration part altogether and just declare your command.
<Button Command="{cmd:HelloWorldCommand}" />
Implementation and Sample
/// <summary> /// Basic implementation of the <see cref="ICommand"/> /// interface, which is also accessible as a markup /// extension. /// </summary> public abstract class CommandExtension<T> : MarkupExtension, ICommand where T:class, ICommand, new() { /// <summary> /// A singleton instance. /// </summary> private static T command; /// <summary> /// Gets a shared command instance. /// </summary> public override object ProvideValue(IServiceProvider serviceProvider) { if (command == null) command = new T(); return command; } /// <summary> /// Fires when changes occur that affect whether /// or not the command should execute. /// </summary> public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } /// <summary> /// Defines the method to be called when the command is invoked. /// </summary> /// <param name="parameter">Data used by the command. /// If the command does not require data to be passed, /// this object can be set to null. /// </param> public abstract void Execute(object parameter); /// <summary> /// Defines the method that determines whether the command /// can execute in its current state. /// </summary> /// <returns> /// This default implementation always returns true. /// </returns> /// <param name="parameter">Data used by the command. /// If the command does not require data to be passed, /// this object can be set to null. /// </param> public virtual bool CanExecute(object parameter) { return true; } }
…and here’s a sample implementation:
public class HelloWorldCommand : CommandExtension<HelloWorldCommand> { public override void Execute(object parameter) { MessageBox.Show("Hello world."); } }
Of course, nothing prevents you from pimping the base class a little to your needs 🙂