Following to How to: Create a RoutedCommand, which demonstrate how to use the Static field to create a RoutedEvent rather than reuse the System RoutedCommand.
Based on that documentaion, and based on the discussion in my previous post - WPF the routed event and routed command, I have come up a slight modified version which demonstrate some alternatives to create Custom RoutedCommand.
Basically I am using the Dependency Property.
public RoutedCommand MyRoutedCommand { get { return (RoutedCommand)GetValue(MyRoutedCommandProperty); } set { SetValue(MyRoutedCommandProperty, value); } } // Using a DependencyProperty as the backing store for MyRoutedCommand. This enables animation, styling, binding, etc... public static readonly DependencyProperty MyRoutedCommandProperty = DependencyProperty.Register("MyRoutedCommand", typeof(RoutedCommand), typeof(MainWindow), new UIPropertyMetadata(null));
Since the CommandBinding Property Element does not accept BindingExtension, so you cannnot write as such
<Window.CommandBindings> <CommandBinding Command="MyRoutedCommand" CanExecute="MyRoutedCommandCanExecute" Executed="MyRoutedCommandExecuted" > </CommandBinding> </Window.CommandBindings>
But you can do the same via the code. here is the code.
private void InitializeCommand()
{
MyRoutedCommand = new RoutedCommand("MyRoutedCommand", this.GetType());
// this is with the code to use the command binding
CommandBinding binding = new CommandBinding();
binding.Command = MyRoutedCommand;
binding.CanExecute += new CanExecuteRoutedEventHandler(MyRoutedCommandCanExecute);
binding.Executed += new ExecutedRoutedEventHandler(MyRoutedCommandExecuted);
this.CommandBindings.Add(binding);
}
You may provide your own handler to CanExecute and Executed.
void MyRoutedCommandExecuted(object sender, ExecutedRoutedEventArgs e) { MessageBox.Show("This is the command window"); } void MyRoutedCommandCanExecute(object sender, CanExecuteRoutedEventArgs e) { //throw new NotImplementedException(); e.CanExecute = true; }
Below is the main code (xaml parts) -- it contains the code of my enhancement as well as the original version from MSDN
<Window x:Class="CommandExecutions.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:CommandExecutions" Title="MainWindow" Height="350" Width="525" DataContext="{Binding RelativeSource={RelativeSource Self}}" > <Window.CommandBindings> <CommandBinding Command="{x:Static local:MainWindow.CustomRoutedCommand}" Executed="ExecuteCustomCommand" CanExecute="CanExecuteCustomCommand" /> </Window.CommandBindings> <StackPanel> <Button Name="myButton" Command="{Binding Path=MyRoutedCommand}" CommandTarget="{Binding RelativeSource={RelativeSource Self}}" Content="{Binding Path=ButtonContext}"/> <Button Name="MyButton2" Command="{x:Static local:MainWindow.CustomRoutedCommand}" Content="CustomRoutedCommand" /> </StackPanel> </Window>
And below is the code-behind file.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.ComponentModel; using System.Diagnostics; namespace CommandExecutions { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window,INotifyPropertyChanged { public MainWindow() { InitializeComponent(); InitializeCommand(); this.ButtonContext = "New Value"; } private void InitializeCommand() { MyRoutedCommand = new RoutedCommand("MyRoutedCommand", this.GetType()); // this is with the code to use the command binding CommandBinding binding = new CommandBinding(); binding.Command = MyRoutedCommand; binding.CanExecute += new CanExecuteRoutedEventHandler(MyRoutedCommandCanExecute); binding.Executed += new ExecutedRoutedEventHandler(MyRoutedCommandExecuted); this.CommandBindings.Add(binding); //this.myButton.CommandBindings.Add(binding); // you can do the same with Xaml code /* <Window.CommandBindings> <CommandBinding Command="MyRoutedCommand" CanExecute="MyRoutedCommandCanExecute" Executed="MyRoutedCommandExecuted" > </CommandBinding> </Window.CommandBindings> */ } void MyRoutedCommandExecuted(object sender, ExecutedRoutedEventArgs e) { MessageBox.Show("This is the command window"); } void MyRoutedCommandCanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = true; } public RoutedCommand MyRoutedCommand { get { return (RoutedCommand)GetValue(MyRoutedCommandProperty); } set { SetValue(MyRoutedCommandProperty, value); } } // Using a DependencyProperty as the backing store for MyRoutedCommand. This enables animation, styling, binding, etc... public static readonly DependencyProperty MyRoutedCommandProperty = DependencyProperty.Register("MyRoutedCommand", typeof(RoutedCommand), typeof(MainWindow), new UIPropertyMetadata(null)); public event PropertyChangedEventHandler PropertyChanged; public void RaisePropertyChanged(string propertyName) { var temp = PropertyChanged; if (temp != null) { temp(this, new PropertyChangedEventArgs(propertyName)); } } public static RoutedCommand CustomRoutedCommand = new RoutedCommand(); private void ExecuteCustomCommand(object sender_, ExecutedRoutedEventArgs e) { MessageBox.Show("Custom Command Executed"); } private void CanExecuteCustomCommand(Object sender_, CanExecuteRoutedEventArgs e) { Control target = e.Source as Control; if (target != null) { e.CanExecute = true; } else { e.CanExecute = false; } } } }