也许是有史以来最长的问题标题!因为这是一个两部分的问题。
(1)我不明白如何设置NotifyOnValidationError =" True"可以触发我的CanExecute更新。我需要了解一些神奇的内容。某人(事物)订阅我的ICommand的CanExecuteChanged事件,但调用堆栈指向外部代码,所以我无法弄清楚发生了什么。
(2)也许最重要的后续问题是:为什么它在MVVM Light RelayCommand中不起作用! CanExecute仅在初始化时调用一次,然后再也不会调用。在MVVM Light中查看RelayCommand的源代码并没有发现与我自己的实现相比的任何阻塞差异。我应该提一下,Prism的DelegateCommand似乎也不起作用。
(Bonus)也许我正在以错误的方式接近这个问题?我只是想基于验证失败来启用/禁用按钮。
XAML(摘录):
<TextBox Grid.Column="1" Grid.Row="0">
<Binding Path="X" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True">
<Binding.ValidationRules>
<ExceptionValidationRule></ExceptionValidationRule>
</Binding.ValidationRules>
</Binding>
</TextBox>
<Button Grid.Column="1" Grid.Row="3" Command="{Binding CalculateCommand}">
Calculate
</Button>
RelayCommand:
public class MyRelayCommand : ICommand
{
readonly Action<object> Execute_;
readonly Predicate<object> CanExecute_;
public MyRelayCommand(Action<object> Execute, Predicate<object> CanExecute)
{
if (Execute == null)
throw new ArgumentNullException("No action to execute for this command.");
Execute_ = Execute;
CanExecute_ = CanExecute;
}
public bool CanExecute(object parameter)
{
return (CanExecute_ == null) ? true : CanExecute_(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
Execute_(parameter);
}
}
视图模型:
private DelegateCommand _calculateCommmand;
public DelegateCommand CalculateCommand
{
get
{
return _calculateCommmand ?? (_calculateCommmand = new DelegateCommand(
() =>
{
Sum = X + X;
},
() =>
{
try
{
Convert.ChangeType(X, TypeCode.Byte);
return true;
}
catch
{
return false;
}
}));
}
}
PS:如果您想购买我的X + X程序,请发送电子邮件至sales@xplusx.com
答案 0 :(得分:1)
(2)我自己想出了这个。您可以选择从两个不同的命名空间中包含RelayCommand,确保使用
using GalaSoft.MvvmLight.CommandWpf;
我仍然在寻找一个很好的答案(1),管道如何根据验证错误引发CanExecutetChanged。
答案 1 :(得分:0)
我认为这取决于ICommand
实施。在你的,我看到public event EventHandler CanExecuteChanged
,你告诉CommandManager
处理命令CanExecute()
方法的调用。如果没有CommandManager,您必须自己处理,例如通过为您的ICommand实现提供public void RaiseCanExecuteChanged()
方法,ViewModel必须为其认为需要重新计算的每个命令调用该方法,例如:在ViewModel的OnPropertyChanged
内。示例:https://codereview.stackexchange.com/questions/124361/mvvm-am-i-doing-it-right
所以CommandManager为你带来了魔力。只要您调用ViewModel的PropertyChanged
事件,就会出现&#34;外部代码&#34;处理受影响的命令并要求他们获得新的CanExecute()
值。
答案 2 :(得分:0)
(1)我认为是这样的。
我想更多地了解上面的第三个要点,所以我会将问题保持一段时间,让专家有机会参与其中。