PropertyChangedEvent和CanExecute问题

时间:2012-04-18 00:56:29

标签: c# wpf mvvm prism wpf-4.0

我正在使用MVVM(prism)来开发wpf应用程序。

我的一个模型类“StandardContact”的属性直接绑定到视图。我使用IDataErrorInfo来跟踪并通知模型是否有任何错误。如果Model中有任何错误,我将禁用“保存”命令。

当用户输入一些数据时,我使用StandardContact.PropertyChanged处理程序来查看是否可以执行“保存”命令(即用户输入的模型数据是否有效)。问题是在IDataErrorInfo的验证代码之前调用StandardContact.PropertyChanged处理程序,因此“保存”命令的CanExecute无法正确反映命令是否可以执行。我正在寻找的是,在CanExecute执行之前,应运行IDataErrorInfo验证,以便CanExecute将查询模型中的最新数据并确定它是否已启用。以下是我正在使用的示例代码

型号:

public class StandardContact :EntityBase, IDataErrorInfo
{
    public virtual string Name 
    {
        get { return _name; }
        set { SetField(ref _name, value, () => Name); }
    }

    //...
    //Validators
    public string this[string propertyName] 
    {
        get 
        {
            string error = null;
        //....
    }

视图模型

public class SContactEditViewModel : NotificationObject, INavigationAware 
{
    //....
        StandardContact.PropertyChanged += 
            new PropertyChangedEventHandler(StandardContact_PropertyChanged);

    void StandardContact_PropertyChanged(object sender, PropertyChangedEventArgs e) 
    {
        //Requery if command can execute
        SaveNewCommand.RaiseCanExecuteChanged(); 
    }
}

2 个答案:

答案 0 :(得分:0)

我不使用prism,但是如果它暴露某种IsValid方法或属性,你可以使用它来触发你的错误检查。如果不是,你可以自己写。

没有棱镜的基本思想是必须通过

来利用IDataErrorInfo.Error
bool IsValid{ get{return string.IsNullOrEmpty(Error) }  // trigger validation

然后在Save.CanExecute方法

return IsValid;    // trigger validation on demand

HTH,
Berryl

答案 1 :(得分:0)

我刚检查了我们的专有MVVM库。在ViewModels索引器内(在您的情况下,这是模型索引器),所请求的属性已经过验证:

public string this[string propertyName]
{
    get
    {
        string result = null;

        if (CanDataErrorValidated(propertyName))
        {
            int errorCount = CurrentValidationAdapter.ErrorCount();
            result = ValidateProperty(propertyName, GetValidateValue(propertyName));

            // if the error flag has been changed after validation
            if (errorCount != CurrentValidationAdapter.ErrorCount())
            {
                RaisePropertyChanged(PropHasError);
                RaisePropertyChanged(PropError);
            }
        }
        else
        {
            RaisePropertyChanged(PropHasError);
            RaisePropertyChanged(PropError);
        }

        return result;
    }
}

因此,您的问题的解决方案似乎可以动态验证所请求的属性。