C# wpf Datagrid:单击保存按钮时获取验证错误

C# wpf Datagrid:单击保存按钮时获取验证错误,c#,wpf,validation,datagrid,wpftoolkit,C#,Wpf,Validation,Datagrid,Wpftoolkit,我有一个datagrid,我使用IDataErrorInfo进行验证。现在,如果单击“保存”按钮验证失败,我想显示错误消息。我的问题是如何获得验证错误,我在web上尝试了很多页面,我真的厌倦了这些。有人知道解决方案吗? 我的数据网格是: <my:DataGrid Name="dgDamagedProducts" ItemsSource="{Binding}" SelectionUnit="Cell" BeginningEdit="dgDamagedProducts_Beginnin

我有一个datagrid,我使用IDataErrorInfo进行验证。现在,如果单击“保存”按钮验证失败,我想显示错误消息。我的问题是如何获得验证错误,我在web上尝试了很多页面,我真的厌倦了这些。有人知道解决方案吗? 我的数据网格是:

 <my:DataGrid Name="dgDamagedProducts" ItemsSource="{Binding}"   SelectionUnit="Cell"  BeginningEdit="dgDamagedProducts_BeginningEdit"  AutoGenerateColumns="False" Margin="13,75,9,117" RowEditEnding="dgDamagedProducts_RowEditEnding" GotFocus="dgDamagedProducts_GotFocus">
                    <my:DataGrid.Columns>
                        <!--0-ProductTransaction ID Column-->
                        <my:DataGridTextColumn  Header="ProductTransaction ID"  Visibility="Hidden" Width="0" Binding="{Binding ProductTransactionID}"></my:DataGridTextColumn>
                        <!--1-Item incID Column-->
                        <my:DataGridTextColumn  Header="ItemID" Visibility="Hidden" Width="0" Binding="{Binding ItemID}"></my:DataGridTextColumn>
                        <!--2-Product Code Column-->
                        <my:DataGridTextColumn  Header="Code" Width="100" Binding="{Binding ProductCode}"></my:DataGridTextColumn>
                        <!--3-Product Column-->
                        <my:DataGridTemplateColumn Header="Product Name" Width="200">
                            <my:DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock Padding="3" Text="{Binding ProductName,NotifyOnValidationError=True,ValidatesOnDataErrors=True}" Style="{StaticResource TextBlockInError}"></TextBlock>
                                </DataTemplate>
                            </my:DataGridTemplateColumn.CellTemplate>
                            <my:DataGridTemplateColumn.CellEditingTemplate>
                                <DataTemplate>
                                    <TextBox x:Name="txtbxProduct" Style="{StaticResource TextBoxInError}" Text="{Binding Path=ProductName,Mode=TwoWay,NotifyOnValidationError=True,ValidatesOnDataErrors=True}" lc:FocusAttacher.Focus="True" TextChanged="txtbxProduct_TextChanged" PreviewKeyDown="txtbxProduct_PreviewKeyDown" ></TextBox>
                                </DataTemplate>
                            </my:DataGridTemplateColumn.CellEditingTemplate>
                        </my:DataGridTemplateColumn>

                        <!--7-Purchase Rate Column-->
                        <my:DataGridTextColumn Header="Purchase Rate" Width="100" Binding="{Binding PurchaseRate}" IsReadOnly="True"></my:DataGridTextColumn>
                        <!--8-Stock  Column-->
                        <my:DataGridTextColumn Header="Stock"  Binding="{Binding AvailableQty}" IsReadOnly="True" Visibility="Hidden"></my:DataGridTextColumn>
                        <!--9-Qty Column-->
                        <my:DataGridTemplateColumn Header="Qty" Width="100">
                            <my:DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding Qty,ValidatesOnDataErrors=True}" Style="{StaticResource TextBlockInError}"></TextBlock>
                                </DataTemplate>
                            </my:DataGridTemplateColumn.CellTemplate>
                            <my:DataGridTemplateColumn.CellEditingTemplate>
                                <DataTemplate>
                                    <RH:IntTextBox  x:Name="txtbxQty" Style="{StaticResource TextBoxInError}" Text="{Binding Qty,Mode=TwoWay,UpdateSourceTrigger=LostFocus,ValidatesOnDataErrors=True}" lc:FocusAttacher.Focus="True" LostFocus="txtbxQty_LostFocus" PreviewKeyDown="txtbxQty_PreviewKeyDown"></RH:IntTextBox>
                                </DataTemplate>
                            </my:DataGridTemplateColumn.CellEditingTemplate>
                        </my:DataGridTemplateColumn>
                        <!--10-Amount Column-->
                        <my:DataGridTextColumn Header="Amount" Width="100" Binding="{Binding Amount}" IsReadOnly="True" ></my:DataGridTextColumn>

                    </my:DataGrid.Columns>
                </my:DataGrid>
接口公开名为Error的属性。这是包含文本错误消息的属性,您在索引器中设置了文本错误消息,必须将其作为接口的一部分实现

请注意,此界面一次仅显示一条错误消息,无需用户自定义。很难给出准确的示例,因为您没有告诉我们实现此接口的类的任何细节。但是,它有点像这样:

您的索引器:

public override string this[string propertyName]
{
    if (propertyName = "Name" && Name == string.Empty) return "Please add the name";
    return string.Empty;
}
当接口看到属性的更改时,它调用此索引器。如果在此处找到属性名称并显示错误消息,则在实现接口的数据类的error属性中设置该消息。因此,要查看消息,只需绑定到Error属性:

<TextBlock Text="{Binding Error}" Foreground="Red" />
<TextBlock Text="{Binding Name}" />
更新2>>>

有许多方法可以获得这些验证错误。一种方法是将要验证的每个属性名传递给indexer方法并返回结果:

public string Error
{
    get
    {
        if (this["Name"] != string.Empty) return this["Name"];
        ...
        else if (this["OtherProperty"] != string.Empty) return this["OtherProperty"];
        return string.Empty;
    }
}
您提到了Validation.Errors属性,您也可以使用该属性,但为此,您需要将和/或属性设置为True。有关这些方面的更多信息,请参阅和文章

我个人不喜欢直接使用这些属性或Error属性。相反,我在基类中有一个名为Errors的抽象集合属性,该属性在派生类中被重写:

public override ObservableCollection<string> Errors
{
    get
    {
        errors = new ObservableCollection<string>();
        errors.AddUniqueIfNotEmpty(this["Name"]);
        errors.AddUniqueIfNotEmpty(this["EmailAddresses"]);
        errors.AddUniqueIfNotEmpty(this["StatementPrefixes"]);
        return errors;
    }
}

正如你所看到的。。。这使我能够一次查看多个错误。

此外,我如何访问codebehind中的错误,我想将其放在messagebox中,但实例。错误总是返回空的,即使我有验证错误。private void btnSave_Clickobject sender,RoutedEventArgs e{clsDamagedProducts obj=new clsDamagedProducts;如果obj.Error.Length>0{MessageBox.Showobj.Error;返回;}当然,您的Error属性返回空的…您这样做了-您是从错误获取程序返回的。我为您更新了我的答案。在MVVM->False链接中使用属性和IDataErrorInfo接口进行WPF验证
public string Error
{
    get
    {
        if (this["Name"] != string.Empty) return this["Name"];
        ...
        else if (this["OtherProperty"] != string.Empty) return this["OtherProperty"];
        return string.Empty;
    }
}
public override ObservableCollection<string> Errors
{
    get
    {
        errors = new ObservableCollection<string>();
        errors.AddUniqueIfNotEmpty(this["Name"]);
        errors.AddUniqueIfNotEmpty(this["EmailAddresses"]);
        errors.AddUniqueIfNotEmpty(this["StatementPrefixes"]);
        return errors;
    }
}