我有以下问题:
我需要能够记录绑定到我代码中按钮的命令。我正在使用的系统的所有按钮都是RelayCommand
。我找到了一个网站,它解释了如何做到这一点,但使用RoutedCommands
。链接是一个帖子的按钮。下面是一个如何使用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;
}
}
}
我的问题是这不适用于RelayCommands
,我不能把所有的RelayCommands
都改成RoutedCommands
。
有人知道如何用RelayCommands
实现这一点吗?
下面是我代码中的一个RelayCommand
示例:
private RelayCommand _closePopupCommand = new RelayCommand(() => Window.PopUpViewModel = null);
public RelayCommand ClosePopupCommand
{
get => _closePopupCommand;
set
{
_closePopupCommand = value;
RaisePropertyChanged();
}
}
和路由事件的代码隐藏:
public readonly RoutedEvent ConditionalClickEvent = EventManager.RegisterRoutedEvent("test", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(Button));
链接到实现RoutedCommands
的网站:https://joshsmithonwpf.wordpress.com/2007/10/25/logging-routed-commands/
我尝试过RelayCommands
,但它们似乎没有RoutedCommands
的功能,我认为这与RoutedEvents
有关,即RoutedCommands
绑定。在我看来,有3个选项:
1.不可能
1.我必须将RelayCommands
更改为RoutedCommands
1.使用类似RegisterEventHandlers
的字符串
2条答案
按热度按时间vmpqdwk31#
也许听Click活动会适合你?
klh5stk12#
您可以在使用
RelayCommand
注册的execute命令处理程序中添加日志记录器输出,甚至可以将日志记录直接移到RelayCommand.Execute
方法中。根据您要记录的内容相关信息,您可能会决定实作可在检视内容中作业的Helper类别,例如,收集已叫用命令之命令来源(通常是控件)的相关信息。
下列范例遗漏取消订阅事件的unregister方法。您必须加入这些方法,才能允许取消订阅事件,以防止内存遗漏。这与类别行程常式无关,但对执行严修行程常式(例如
RelayCommand.Executed
事件)很重要。1.为了提供与
RoutedCommand
相同的信息,例如源、目标和命令名,您需要扩展RelayCommand
。为了避免通过引入派生类型破坏现有代码,您可以直接修改RelayCommand
源。以下命令(取自Microsoft文档:Relaying Command Logic)公开了一个
Name
和一个Target
属性以及一个Executed
事件。这两个属性是可选的,但如果要提供命令名称和命令目标(执行命令处理程序的类型,例如视图模型类)等信息,则建议使用这两个属性:中继命令.cs
1.然后创建一个数据类型来携带收集的命令上下文信息:
命令上下文.cs
1.创建提供命令执行上下文的实际帮助器类
CommandContextTracer
。其思想是注册一个全局
RoutedCommand
处理程序来跟踪RoutedCommand
调用并收集上下文信息。对于“普通”
ICommand
实现,我们注册一个全局(类级别)ButtonBase.ClickEvent
处理程序(假设所有命令都由ButtonBase
调用)。当然,您可以扩展该类,以提供一个方法来显式注册任何命令或使触发事件动态化(例如,侦听
Click
事件以外的任何其他事件)。CommandContextTracer
将接受它在命令执行时调用的Action<CommandContext>
委托。为了简单起见,类
CommandContextTracer
是一个static
类。如果您使用依赖注入,我强烈建议将static
类转换为一个具有示例成员的普通类。然后将一个共享示例注入到您的视图中(或一般定义命令的类)。虽然视图(即扩展UIElement
的类型)可以匿名注册,如果命令不是由UIElement
调用的,则其他类必须显式地注册它们的命令。命令上下文跟踪器.cs
用法示例
主窗口.xaml.cs
第一种情况将记录源为控件的所有命令调用:
文本视图模型.cs
第二个案例会记录来源不是控件的命令引动过程。
它还显示了如何创建修改后的
RelayCommand
的示例:主窗口.xaml
日志消息