编辑:再次查看您的问题,我认为这比看起来要简单得多
我能看到您遇到的唯一问题是子 VM 上缺少处理程序(和保护)方法意味着在当前活动 VM 上没有实现的按钮仍将启用。
CM 的默认策略是尝试找到匹配的方法名称(在解析操作文本之后),如果找不到,则不理会按钮。如果您要自定义该行为以便默认禁用按钮,则只需在 shell 中实现命令按钮即可轻松使其工作,确保将命令目标设置为活动项:
在 shell 中定义你的按钮,确保它们有一个指向活动子虚拟机的目标
<Button cal:Message.Attach="Command1" cal:Action.TargetWithoutContext="{Binding ActiveItem}" />
然后照常在您的子虚拟机中实现该方法
public void Command1() { }
以及可选的 CanXX 警卫
public bool CanCommand1
{
get
{
if(someCondition) return false;
return true;
}
}
假设你没有比这更复杂,它应该适合你
我将快速浏览一下 CM 源代码,看看我是否能想出一些适用于此的方法
编辑:
好的,您可以自定义ActionMessage.ApplyAvailabilityEffect func 以获得您想要的效果 - 在您的 bootstrapper.Configure() 方法中(或在启动时的某处)使用:
ActionMessage.ApplyAvailabilityEffect = context =>
{
var source = context.Source;
if (ConventionManager.HasBinding(source, UIElement.IsEnabledProperty))
{
return source.IsEnabled;
}
if (context.CanExecute != null)
{
source.IsEnabled = context.CanExecute();
}
// Added these 3 lines to get the effect you want
else if (context.Target == null)
{
source.IsEnabled = false;
}
// EDIT: Bugfix - need this to ensure the button is activated if it has a target but no guard
else
{
source.IsEnabled = true;
}
return source.IsEnabled;
};
这似乎对我有用 - 没有不能绑定到命令的方法的目标,所以在这种情况下,我只需将 IsEnabled 设置为 false。仅当在活动子 VM 上找到具有匹配签名的方法时才会激活按钮 - 显然在使用之前对其进行很好的测试:)