C# WPF:DataGrid在所有DataGridTemplateColumns上显示验证错误

C# WPF:DataGrid在所有DataGridTemplateColumns上显示验证错误,c#,wpf,validation,datagrid,C#,Wpf,Validation,Datagrid,我有一个简单的标准WPF4数据网格,有两列 <DataGrid ItemsSource="{Binding Source={StaticResource ItemDataView}}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTemplateColumn Header="Alpha"> <DataGridTemplateColumn.

我有一个简单的标准WPF4数据网格,有两列

<DataGrid ItemsSource="{Binding Source={StaticResource ItemDataView}}" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="Alpha">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Alpha}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTemplateColumn Header="Beta">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Beta}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

显示的数据对象定义如下:

public class MyObject : INotifyDataErrorInfo
{
    [Required]
    public string Alpha { get; set; }

    public string Beta { get; set; }

    public bool HasErrors
    {
        get { return string.IsNullOrEmpty(Alpha); }
    }

    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

    public IEnumerable GetErrors(string propertyName)
    {
        yield return propertyName;
    }
}
公共类MyObject:INotifyDataErrorInfo
{
[必需]
公共字符串Alpha{get;set;}
公共字符串Beta{get;set;}
公共布尔错误
{
获取{返回字符串.IsNullOrEmpty(Alpha);}
}
公共事件事件处理程序错误更改;
公共IEnumerable GetErrors(字符串propertyName)
{
收益率返回属性名称;
}
}
i、 e.Alpha必须具有非空值,但Beta可以为空

如果我添加一个Alpha值为空的MyObject,那么Alpha和Beta单元格都会显示一个红色边框,表示验证错误。这仅适用于DataGridTemplateColumns;我尝试添加DataGridTextColumn,但它没有红色边框。如果Beta列没有绑定到任何东西,或者即使它没有附加控件(例如DataTemplate为空),它也会得到一个红色边框

a) 为什么会发生这种情况


b) 我怎样才能阻止它发生?我只想在有错误的单元格上显示红色验证边框。

INotifyDataErrorInfo
用于确定是否存在错误。具体地说,必须实现
hasrerrors
属性以返回true或false来指示是否存在错误。在您的例子中,
hasrerrors
实现只查看
Alpha

public bool HasErrors
{
    get { return string.IsNullOrEmpty(Alpha); }
}
因此,只有当
Alpha
为null或空时,才会显示有错误

您需要对其进行修改以同时选中这两个选项,如下所示:

public bool HasErrors
{
    get 
    {
       return !AlphaIsValid || !BetaIsValid;
    }
}

private bool AlphaIsValid
{
    get {return !string.IsNullOrEmpty(Alpha);}
}

private bool BetaIsValid
{
    get {return Beta == null || Beta != "";}
}
public IEnumerable GetErrors(string propertyName)
{
    if (propertyName == nameof(Alpha) && !AlphaIsValid)
    {
        return new []{"Alpha is null or empty"};
    }
    if (propertyName == nameof(Beta)  && !BetaIsValid)
    {
        return new []{"Beta is empty"};
    }
    return Enumerable.Empty<string>();
}
然后,在
GetErrors()
中,检查传入的字符串是否匹配
Alpha
Beta
,并为每个字符串提供错误消息,如下所示:

public bool HasErrors
{
    get 
    {
       return !AlphaIsValid || !BetaIsValid;
    }
}

private bool AlphaIsValid
{
    get {return !string.IsNullOrEmpty(Alpha);}
}

private bool BetaIsValid
{
    get {return Beta == null || Beta != "";}
}
public IEnumerable GetErrors(string propertyName)
{
    if (propertyName == nameof(Alpha) && !AlphaIsValid)
    {
        return new []{"Alpha is null or empty"};
    }
    if (propertyName == nameof(Beta)  && !BetaIsValid)
    {
        return new []{"Beta is empty"};
    }
    return Enumerable.Empty<string>();
}
公共IEnumerable GetErrors(字符串propertyName) { if(propertyName==nameof(Alpha)&&!AlphaIsValid) { 返回新的[]{“Alpha为null或空”}; } if(propertyName==nameof(Beta)和&!BetaIsValid) { 返回新[]{“Beta为空”}; } 返回可枚举的.Empty(); } 如果属性没有错误,则返回空集合

目前,您正在为这两个属性返回一个值(因为您只是返回属性名称),因此这两个属性都被标记为存在验证错误


仅供参考:

您的HasErrors函数只返回Alpha的求值。所以Beta单元将只镜像Alpha单元的任何条件。修改Beta上的检查以允许null,这是一个非常好的答案。@PaulGibson谢谢。我忽略了那部分。答案更新。我把问题简单化了,在阅读了你的参考链接后,我现在看到了我实际代码中的问题。我使用的是GetErrors的一个实现,如果参数为null,它将返回所有验证错误。该引用指示在这种情况下只应返回实体级别的错误。对于任何DataGridTemplateColumn,无论是否具有绑定,似乎都会使用null参数调用GetErrors。