关于c#:什么时候使用null vs String.empty调用INotifyDataErrorInfo.GetErrors?

When is INotifyDataErrorInfo.GetErrors called with null vs String.empty?

在inotifyDataErrorInfo.getErrors的msdn页中,它表示使用参数调用getErrors方法,该参数可以是:

  • 要为其检索错误信息的属性的名称
  • 无效的
  • 空字符串

文档没有说明何时使用空值vs string.empty调用此方法。我已经在我的应用程序中看到了这两种情况,我需要理解什么时候我能预料到其中一种情况。

澄清:我不是在问我应该如何实现getErrors方法(我只是测试空值和空值)。问题更多的是理解为什么WPF框架尝试调用这个方法,有时使用空字符串,有时使用空字符串(我在应用程序中遇到了这两种情况)。如果目的是询问与特定属性无关的错误,为什么在只有一个值足够的情况下对调用使用两个不同的值?


wpf调用inotifyDataErrorInfo.getErrors(null/string.empty)以获取"整个视图模型"的错误。所有具有数据上下文或绑定到具有"整个视图模型错误"的视图模型的控件都将使用错误模板呈现。例如,您有两个属性的视图模型凭据:用户名、密码。您可以实现如下功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
IEnumerable InotifyDataErrorInfo.GetErrors(string propertyName)
    {
        if (UserNames.Length == 0)
        {
            if (string.IsNullOrEmpty(propertyName))
            {
                return"Some credentials component is wrong.";
            }
            else if (propertyName =="UserNames")
            {
                return"User name is required field.";
           }
        }
    }

但是,在大多数情况下,当字符串.IsNullOrEmpty(PropertyName)时,您可能返回空值。


当调用者不想知道某个特定参数的错误,而想知道实体所有参数的错误时,您必须同时看到nullstring.Empty。所以你不应该在nullstring.Empty之间做任何区别。

所以就这样:

1
2
3
4
5
6
7
8
if(string.IsNullOrEmpty(propertyName))
{
    // return all errors
}
else
{
    // return the error for the parameter 'propertyName'
}


当绑定未引用任何属性时,您将获得空参数,与默认路径一样:

1
2
DataContext="{Binding ValidatesOnNotifyDataErrors=True}"
DataContext="{Binding Path=., ValidatesOnNotifyDataErrors=True}"

这可以通过在路径中指定实际属性来避免。当然,它可以是视图模型中的一个属性,包括只返回"this"的属性。

1
Tag="{Binding Path=DataContext, RelativeSource={RelativeSource Self}, ValidatesOnNotifyDataErrors=True}"

对于string.emtpy,这在内部bindingExpression.updateNotifyDataErrors方法的框架中是显式的:

1
2
3
List<object> propertyErrors = GetDataErrors(indei, propertyName);
List<object> valueErrors = GetDataErrors(dataErrorValue, String.Empty);
List<object> errors = MergeErrors(propertyErrors, valueErrors);

警告:请注意上面的聚合操作,因此,如果使用string.isNullOrEmpty验证框架是否请求实体级错误,并返回相同的错误,而不管"null"与string.emtpy是什么,您可能会在UI中得到重复的消息(一个表示"null",另一个表示string.empty)。至少在今天的.NET框架版本中。


何时调用InotifyDataErrorInfo.GetErrors时使用空与字符串.Empty?

如果要验证单个属性,将调用

1
RaiseEvent ErrorsChanged(Me, New DataErrorsChangedEventArgs("PropertyName"))

来自该属性的设置者。

如果要验证整个实体,您将调用

1
RaiseEvent ErrorsChanged(Me, New DataErrorsChangedEventArgs(String.Empty))

从一些"中心"位置,如保存按钮单击,或窗口关闭。