I'm interested in creating commands that are available from anywhere in my WPF application.
I'd like them to work in the same way as Cut
, Copy
, Paste
and the other Application level commands, ie:
<Button Command="Paste" />
I assumed I could setup CommandBindings for the Application instance, but that property isn't available.
How is this done?
The best I have managed so far is to create a suite of commands on the top level window and then access them like this...:
<Button Command="{x:Static namespace::MainWindow.CommandName}" />
Which works, but is of course tightly coupled, and so extremely brittle.
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" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With