c# - 使用 fluentvalidation 验证数据网格时出现问题
问题描述
我是 WPF 的新手,我正在努力通过使用 FluentValidation 来验证 DataGrid 我想要验证 Datagrid 中的每一行问题是一些行,即使它们是验证的,它表明它们无效
这是 DataGrid 的奇怪行为的屏幕截图
这是我正在使用的代码
班级
public class DetailFacture : INotifyPropertyChanged, IDataErrorInfo , IEditableObject { private DetailFactureValidator _detailFactureValidator; private string _libellePiece; private decimal _montantHT; private decimal _tauxTVA; private string _compteCharge; private string _compteTva; private string _codeTva; public DetailFacture ( ) { _detailFactureValidator = new DetailFactureValidator( ); } public string LibellePiece { get { return _libellePiece; } set { _libellePiece = value; OnPropertyChanged( "LibellePiece" ); } } public decimal MontantHT { get { return _montantHT; } set { _montantHT = value; OnPropertyChanged( "MontantHT" ); } } public decimal TauxTVA { get { return _tauxTVA; } set { _tauxTVA = value; OnPropertyChanged( "TauxTVA" ); } } public string CompteCharge { get { return _compteCharge; } set { _compteCharge = value; OnPropertyChanged( "CompteCharge" ); } } public string CompteTva { get { return _compteTva; } set { _compteTva = value; OnPropertyChanged( "CompteTva" ); } } public string CodeTva { get { return _codeTva; } set { _codeTva = value; OnPropertyChanged( "CodeTva" ); } } public string Error { get { if ( _detailFactureValidator != null ) { var results = _detailFactureValidator.Validate( this ); if ( results != null && results.Errors.Any( ) ) { var errors = string.Join( Environment.NewLine , results.Errors.Select( x => x.ErrorMessage ).ToArray( ) ); return errors; } } return string.Empty; } } public string this[ string columnName ] { get { var firstOrDefault = _detailFactureValidator.Validate( this ).Errors.FirstOrDefault( lol => lol.PropertyName == columnName ); if ( firstOrDefault != null ) return _detailFactureValidator != null ? firstOrDefault.ErrorMessage : ""; return ""; } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged ( string propertyName ) { PropertyChanged?.Invoke( this , new PropertyChangedEventArgs( propertyName ) ); } private DetailFacture backupCopy; private bool inEdit; public void BeginEdit ( ) { if ( inEdit ) return; inEdit = true; backupCopy = this.MemberwiseClone( ) as DetailFacture; } public void CancelEdit ( ) { if ( !inEdit ) return; inEdit = false; this.CodeTva = backupCopy.CodeTva; this.CompteCharge = backupCopy.CompteCharge; this.CompteTva = backupCopy.CompteTva; this.LibellePiece = backupCopy.LibellePiece; this.MontantHT = backupCopy.MontantHT; this.TauxTVA = backupCopy.TauxTVA; } public void EndEdit ( ) { if ( !inEdit ) return; inEdit = false; backupCopy = null; } }
验证器
public class DetailFactureValidator : AbstractValidator<DetailFacture> { public DetailFactureValidator ( ) { RuleFor( det => det.CodeTva ).NotNull( ).WithMessage( "CodeTva ne doit pas être vide" ) .ExclusiveBetween("32" , "44").WithMessage("Code Tva doit etre entre 32 et 44") .Matches( @"\w*" ).WithMessage( "CodeTva n'est pas une chaîne de caractères" ); RuleFor( det => det.CompteCharge ).NotNull( ).WithMessage( "CompteCharge ne doit pas être vide" ) .Matches( @"\w*" ).WithMessage( "CompteCharge n'est pas une chaîne de caractères" ); RuleFor( det => det.CompteTva ).NotNull( ).WithMessage( "CompteTva ne doit pas être vide" ) .Matches( @"\w*" ).WithMessage( "CompteTva n'est pas une chaîne de caractères" ); RuleFor( det => det.LibellePiece ).NotNull( ).WithMessage( "LibellePiece ne doit pas être vide" ) .Matches( @"\w*" ).WithMessage( "LibellePiece n'est pas une chaîne de caractères" ); } }
Xaml
<UserControl.Resources>
<Style x:Key="errorStyle" TargetType="{x:Type TextBox}">
<Setter Property="Padding" Value="-2"/>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="DataGridCell">
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="BorderThickness" Value="0"/>
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGridCell_PreviewMouseLeftButtonDown" />
</Style>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="ValidationErrorTemplate">
<Setter.Value>
<ControlTemplate>
<Image Source="/Images/Alerte.png" ToolTip="{Binding RelativeSource={ RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}, Path=(Validation.Errors)[0].ErrorContent}" Margin="0" Width="11" Height="11" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<DataGrid x:Name="grille" Grid.ColumnSpan="2" CanUserAddRows="True" ItemsSource="{Binding FactureDetailList, Mode=TwoWay ,ValidatesOnDataErrors=True,ValidatesOnNotifyDataErrors=True,UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="False" Background="#FF06C257" BorderBrush="#FF02401D" Foreground="#FF929292" BorderThickness="0" CanUserResizeColumns="False" >
<DataGrid.Columns>
<DataGridTextColumn Header="Libelle Piece" EditingElementStyle="{StaticResource errorStyle}" Binding="{Binding LibellePiece, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
<DataGridTextColumn Header="Montant HT" EditingElementStyle="{StaticResource errorStyle}" Binding="{Binding MontantHT, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
<DataGridTextColumn Header="Taux TVA" EditingElementStyle="{StaticResource errorStyle}" Binding="{Binding TauxTVA, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
<DataGridTextColumn Header="Compte Charge" EditingElementStyle="{StaticResource errorStyle}" Binding="{Binding CompteCharge, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
<DataGridTextColumn Header="Compte Tva" EditingElementStyle="{StaticResource errorStyle}" Binding="{Binding CompteTva, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
<DataGridTextColumn Header="Code Tva" EditingElementStyle="{StaticResource errorStyle}" Binding="{Binding CodeTva, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
</DataGrid.Columns>
</DataGrid>
- Xaml.cs
public partial class FormulaireUC : UserControl
{
private ObservableCollection<DetailFacture> FactureDetailList;
public FormulaireUC ( )
{
InitializeComponent( );
grille.ItemsSource = FactureDetailList;
}
}
解决方案
推荐阅读
- php - 使用 AWS PHP 开发工具包上传到 AWS S3 身份验证失败
- xamarin - 以单独的形式使用 App 类中的方法 xamarin
- c++ - 解构 SDL_Texture 是否调用 SDL_DestroyTexture?
- nginx - Nginx Laravel 和 phpmyadmin 配置
- bootstrap-4 - 如何修复只有div没有表单的搜索表单
- java - 模拟器无法启动:等待设备时出错
- reactjs - 找不到模块:无法解析“C:\Users\adcal\dvmtn7\myapp\node_modules\react-dom\cjs”中的“计划”
- three.js - three.js 骨骼控制/可视化和骨骼动画
- r - R中嵌套循环的输出结果
- ios - 如何解析单个 JSON 对象数组?