I have the following problem:
I need to be able to log commands bound to the buttons in my code. The system that I am working on has all it's buttons as RelayCommand
.
I have found a website that explains how to do this, but with RoutedCommands
. The link is a the button of the post. Here is an example of how it works with RoutedCommands
:
public partial class Window1 : System.Windows.Window
{
public Window1()
{
InitializeComponent();
CommandManager.AddPreviewExecutedHandler(this, this.OnPreviewCommandExecuted);
CommandManager.AddCanExecuteHandler(this, this.OnCommandCanExecute);
}
void OnPreviewCommandExecuted(object sender, ExecutedRoutedEventArgs e)
{
StringBuilder msg = new StringBuilder();
msg.AppendLine();
RoutedCommand cmd = e.Command as RoutedCommand;
string name = cmd == null ? "n/a" : cmd.Name;
msg.AppendFormat(" Name={0}; Parameter={1}; Source={2}", name, e.Parameter, e.Source);
msg.AppendLine();
Logger.Log(msg.ToString());
}
void OnCommandCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
// For the sake of this demo, just allow all
// commands to be executed.
e.CanExecute = true;
}
}
}
My problem is this doesn't work with RelayCommands
and I can't afford to change all the RelayCommands
to RoutedCommands
.
Does anybody know how this can be implemented with RelayCommands
?
Here is a example of a RelayCommand
in my code:
private RelayCommand _closePopupCommand = new RelayCommand(() => Window.PopUpViewModel = null);
public RelayCommand ClosePopupCommand
{
get => _closePopupCommand;
set
{
_closePopupCommand = value;
RaisePropertyChanged();
}
}
And a the codebehind to route events:
public readonly RoutedEvent ConditionalClickEvent = EventManager.RegisterRoutedEvent("test", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(Button));
Link to the website that implements RoutedCommands
:
https://joshsmithonwpf.wordpress.com/2007/10/25/logging-routed-commands/
I have tried with RelayCommands
but they don't seem to have the same functionality as RoutedCommands
I think it has to do with the RoutedEvents
, that RoutedCommands
binds.
From what I see, there are 3 options:
RelayCommands
to RoutedCommands
RegisterEventHandlers
Perhaps listening to the Click event will suit you?
public MainWindow()
{
InitializeComponent();
AddHandler(ButtonBase.ClickEvent, (RoutedEventHandler)OnClickLoger, true);
}
private void OnClickLoger(object sender, RoutedEventArgs e)
{
if (e.Source is ButtonBase button && button.Command is ICommand command)
{
if (command is RoutedCommand routedCommand)
{
Debug.WriteLine($"Button: Name=\"{button.Name}\"; RoutedCommand=\"{routedCommand.Name}\"; CommandParameter={button.CommandParameter} ");
}
else
{
var be = button.GetBindingExpression(ButtonBase.CommandProperty);
if (be is null)
{
Debug.WriteLine($"Button: Name=\"{button.Name}\"; Command=\"{command}\"; CommandParameter={button.CommandParameter} ");
}
else
{
Debug.WriteLine($"Button: Name=\"{button.Name}\"; Command Path=\"{be.ParentBinding.Path.Path}\"; CommandParameter={button.CommandParameter} ");
}
}
}
}