WPF Commands, How to declare Application level commands?
You can setup CommandBindings for "All Windows" of your WPF application and implement command handlers in Application class.
First of all, create a static command container class. For example,
namespace WpfApplication1 { public static class MyCommands { private static readonly RoutedUICommand doSomethingCommand = new RoutedUICommand("description", "DoSomethingCommand", typeof(MyCommands)); public static RoutedUICommand DoSomethingCommand { get { return doSomethingCommand; } } }}
Next, set your custom command to Button.Command like this.
<Window x:Class="WpfApplication1.MainWindow" ... xmlns:local="clr-namespace:WpfApplication1"> <Grid> ... <Button Command="local:MyCommands.DoSomethingCommand">Execute</Button> </Grid></Window>
Finally, implement the command handler of your custom command in Application class.
namespace WpfApplication1 { public partial class App : Application { public App() { var binding = new CommandBinding(MyCommands.DoSomethingCommand, DoSomething, CanDoSomething); // Register CommandBinding for all windows. CommandManager.RegisterClassCommandBinding(typeof(Window), binding); } private void DoSomething(object sender, ExecutedRoutedEventArgs e) { ... } private void CanDoSomething(object sender, CanExecuteRoutedEventArgs e) { ... e.CanExecute = true; } }}
I did not like the complexity of the other solutions, but after a few hours of research I found out it is really simple.
First setup your command as you usually do, but add a static property for WPF so that it can obtain an instance of your command.
class MyCommand : ICommand{ // Singleton for the simple cases, may be replaced with your own factory public static ICommand Instance { get; } = new MyCommand(); public bool CanExecute(object parameter) { return true; // TODO: Implement } public event EventHandler CanExecuteChanged; public void Execute(object parameter) { // TODO: Implement } }
Add a reference to the namespace of your command in your XAML (last line), like this:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:commands="clr-namespace:MyProject.Commands">
Then just reference your static property in your XAML like this:
<Button Content="Button" Command="commands:MyCommand.Instance" />
StackOverflow members helped me so many time that I decide now to contribute and share ;-)
Based on Shou Takenaka's answer, here is my implementation.
My interest was to produce only one reusable file.
First, create a command(s) container class
namespace Helpers{ public class SpecificHelper { private static RoutedUICommand _myCommand = new RoutedUICommand("myCmd","myCmd", typeof(SpecificHelper)); public static RoutedUICommand MyCommand { get { return _myCommand; } } static SpecificHelper() { // Register CommandBinding for all windows. CommandManager.RegisterClassCommandBinding(typeof(Window), new CommandBinding(MyCommand, MyCommand_Executed, MyCommand_CanExecute)); } // TODO: replace UIElement type by type of parameter's binded object #region MyCommand internal static void MyCommand_Executed(object sender, ExecutedRoutedEventArgs e) { if (!verifType<UIElement>(e.Parameter)) return; e.Handled = true; // TODO : complete the execution code ... } internal static void SelectAll_CanExecute(object sender, CanExecuteRoutedEventArgs e) { if (!verifType<UIElement>(e.Parameter)) return; e.CanExecute = true; var item = (e.Parameter as UIElement); // TODO : complete the execution code ... } #endregion private static bool verifType<T>(object o) { if (o == null) return false; if (!o.GetType().Equals(typeof(T))) return false; return true; } }}
Next, declare a resource in App.xaml:
<Application x:Class="Helper.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:h="clr-namespace:Helpers" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" StartupUri="MainWindow.xaml" > <Application.Resources> <h:SpecificHelper x:Key="sh" /> </Application.Resources></Application>
Finally, bind any command property to the property of your application resource:
<Button Content="Click to execute my command" Command="{Binding Source={StaticResource sh}, Path=MyCommand}" CommandParameter="{Binding ElementName=myElement}" />
that's all folks :-)