我将CommandParameter传递给我的命令
时遇到问题我有命令:
private Command<Boolean> _setAsCompletedCommand;
public Command<Boolean> SetAsCompletedCommand
{
get
{
return _setAsCompletedCommand ?? (_setAsCompletedCommand = new Command<Boolean>(isToComplete =>
{
if (isToComplete)
{
//do something
}
else
{
//do something else
}
}, isToComplete =>
{
if (isToComplete)
{
//check something
}
else
{
//check something else
}
}));
}
}
我尝试传递system:Boolean,如下所示:
<Button
Command="{Binding SetAsCompletedCommand}">
<Button.CommandParameter>
<system:Boolean>
True
</system:Boolean>
</Button.CommandParameter>
</Button>
问题是,在构建视图时,我的SetAsCompletedCommand.CanExecute()
是使用False
参数执行的。
怎么可能?我该如何解决?
当我点击按钮时,CommandParameter
已正确设置为True
我在这个项目中使用Catel框架作为MVVM框架。但我认为它不会产生问题。
答案 0 :(得分:0)
首先,我不会以这种方式创建属性。你应该坚持使用简单的属性,让命令本身完成所有的工作。我建议编写一个自定义命令,让它继承自这样的命令基类:
using System;
using System.Windows.Input;
namespace MyCommands
{
/// <summary>
/// Base class for all Commands.
/// </summary>
public abstract class CommandBase : ICommand
{
/// <summary>
/// Defines the method that determines whether the command can execute in its current
/// state.
/// </summary>
/// <param name="parameter">Data used by the command. If the command does not require data
/// to be passed, this object can be set to null.</param>
/// <returns>
/// true if this command can be executed; otherwise, false.
/// </returns>
public virtual bool CanExecute(object parameter)
{
return true;
}
/// <summary>
/// Defines the method to be called when the command is invoked.
/// </summary>
/// <param name="parameter">Data used by the command. If the command does not require data
/// to be passed, this object can be set to null.</param>
public virtual void Execute(object parameter) {}
/// <summary>
/// Occurs when changes occur that affect whether or not the command should execute.
/// </summary>
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
}
}
在那里,您可以通过分别覆盖 CanExecute 和执行来指定允许命令执行的条件以及执行命令时应执行的操作。
答案 1 :(得分:0)
这非常棘手,是由绑定执行的顺序引起的。一旦绑定更新,WPF就会在您的命令上运行CanExecute。 在此阶段 CommandParameter尚未绑定,Catel使用布尔值(.htaccess
)的默认值作为命令参数。
之后,只有在属性更改时才会重新评估命令。例如,除非属性更改,否则Catel没有理由使状态的命令无效。
解决此问题的一个解决方案是在视图模型的false
中使用CommandManager.InvalidateCommands(true)
。这将使vm上的所有命令的状态无效并重新评估它们(在此阶段,命令参数的绑定是正确的。)
您可能会问自己:“为什么不在初始化方法中自动重新评估?”。
嗯,我们过去做过,但我们希望提供更好的开箱即用性能。这可能是您第一次使用命中参数来达到此限制,但我认为您过去创建了更多命令。这意味着到目前为止你在所有其他命令上都有性能改进,所以我仍然认为这是一个很好的决定。还有足够的解决方法来恢复旧的行为,它使用InitializeAsync
的WPF来重新评估几乎每个路由事件(鼠标移动,键盘等)上的命令。