在我的ViewModel中,我实现了IDataErrorInfo
接口(连同INotifyPropertyChanged
)。输入验证按预期工作,我在那里没有问题。
我将此属性作为IDataErrorInfo
的一部分
public string Error { get { return this[null]; } }
据我所知,如果所有验证的输入都通过了验证,Error
应该是空的,所以我将其作为CanExecute方法传递
return !string.IsNullOrEmpty(Error);
但是,我的“保存”按钮从未启用。我猜CanExecuteChanged
永远不会被触发。如果这是真的,我应该在哪里以及如何触发它?
这是我的RelayCommand
类。我尝试过其他的实施方式,但结果是一样的。我认为它是可行的,因为如果我不将CanExecute
方法传递给构造函数,“save”按钮就会被启用。
public class RelayCommand : ICommand
{
private readonly Action execute;
private readonly Func<bool> canExecute;
public RelayCommand(Action execute, Func<bool> canExecute = null)
{
this.execute = execute;
this.canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return canExecute == null || canExecute();
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter) { execute(); }
}
“保存”按钮:
<Button Content="Save" Command="{Binding InsertCommand}"/>
插入命令:
public RelayCommand InsertCommand { get; internal set; }
在ViewModel构造函数中:
InsertCommand = new RelayCommand(ExecuteInsert, CanExecuteInsert);
CanExecute:
bool CanExecuteInsert()
{
return !string.IsNullOrEmpty(Error);
}
1条答案
按热度按时间hrysbysz1#
您还没有添加足够的代码,我们无法准确地告诉您问题所在。但是,你正在采取正确的方法。我也使用
IDataErrorInfo
接口,但我在实现它的基类中添加了一些额外的属性:Errors
集合只是让我能够同时维护多个错误,HasError
只是告诉我是否有任何错误。Errors
集合使用IDataErrorInfo
索引器填充每种数据类型:所以为了回答你的实际问题,我会这样处理
Save Command
的CanExecute
功能:所以,看起来好像你是在用几乎相同的方式做这件事--我的附加属性当然是可选的。如果你的
Error
属性永远不为空,那么我会说 * 那 * 是你的问题。首先调试它,看看它实际上有什么价值……也许总是有一个不应该出现的错误啊...我刚刚注意到你的
Error
属性代码... * 这是你的问题:您使用
null
值调用索引器,因此索引器中的代码返回的实际上是Error
属性值。如果没有验证错误,索引器也应该返回空字符串:然后,在
Error
属性中,您应该像我在Errors
属性中所做的那样调用您想要验证的 actual 属性名称,而不是 *null
。所以在上面的例子中,你可以在Error
属性中调用这样的函数:又一次,我写了太多的信息……我只希望这一切对你来说都是有意义的,你不会带着几十个新问题回来。希望已经够清楚了。