WPF DataGrid验证错误未清除

时间:2011-02-24 00:27:05

标签: wpf validation datagrid wpfdatagrid idataerrorinfo

所以我有一个WPF DataGrid,它绑定到ObservableCollection。该集合通过IDataErrorInfo对其成员进行了验证。如果我以某种方式编辑单元格以使其无效,然后在击中输入之前将其标记离开它,然后返回并使其有效,单元格将停止显示无效,但是,“!”行的开头仍然在那里,ToolTip将引用前一个无效值。

16 个答案:

答案 0 :(得分:22)

不使用Mode=TwoWay DataGridTextColumns来解决问题的一个版本,但是由于其他原因,这个问题似乎无处不在。

(对于为什么不使用Mode=TwoWay解释这一问题的人有一个很好的解释,可能接近这个问题的解决方案)

同样的事情发生在我身上DataGridComboBoxColumn所以我试图深入挖掘一下。

问题不在于显示Binding Control ErrorTemplate的{​​{1}} DataGridHeaderBorder。它将VisibilityValidation.HasError绑定到祖先DataGridRow(正如它应该做的那样)并且该部分正在运行。

Visibility="{Binding (Validation.HasError),
                     Converter={StaticResource bool2VisibilityConverter},
                     RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}"/>

问题是验证错误在解析后不会从DataGridRow中清除。在我的问题版本中,DataGridRow以0错误开始。当我输入一个无效值时,它得到1个错误,所以到目前为止一切都很好。但是当我解决错误时,它跳到了3个错误,所有错误都相同。

我尝试使用DataTrigger解决此问题,如果ValidationErrorTemplate不是1,则将{x:Null}设置为Validation.Errors.Count。它在第一次迭代时效果很好但是一次我第二次清除了错误。它不再有3个错误,它有7个!经过几次迭代后,它超过了10。

我还尝试通过UpdateSource上的UpdateTargetBindingExpressions手动清除错误,但没有骰子。 Validation.ClearInvalid也没有任何影响。查看工具包中的源代码并没有让我随处可见:)

所以我没有任何好的解决方案,但我认为我应该发布我的发现..

到目前为止我唯一的“解决方法”是隐藏ErrorTemplate中的DataGridRowHeader

<DataGrid ...>
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
            <Setter Property="ValidationErrorTemplate" Value="{x:Null}"/>
        </Style>
    </DataGrid.RowStyle>
    <!-- ... -->
</DataGrid>

答案 1 :(得分:5)

我找到了最适合我的答案。只需清除DataGrid的{​​{1}}。

即可
  1. 在代码中

    RowValidationErrorTemplate
  2. 在Xaml

    YourGrid.RowValidationErrorTemplate = new ControlTemplate();
    
  3. 然后制作您自己的行验证错误模板。

    如果您的数据项是 INotifyPropertyChanged

    <DataGrid.RowValidationErrorTemplate>
        <ControlTemplate>
        </ControlTemplate>
    </DataGrid.RowValidationErrorTemplate>`
    

    然后

    ((INotifyPropertyChanged)i).PropertyChanged += this.i_PropertyChanged;`
    
  4. 按您喜欢的方式编写自己的IsValid方法

答案 2 :(得分:2)

我的解决方案是实现自定义行验证反馈,类似于 自定义行验证反馈 部分下的this page。行错误然后适当地消失。

(我还在RowHeaderWidth="20"定义中添加了DataGrid,以避免在感叹号第一次出现时向右移动表。)

答案 3 :(得分:2)

我遇到的问题是RowHeader错误模板不会消失。我正在使用INotifyDataErrorInfo。继Fredrik Hedblad的研究之后,我做了一个解决方法;我修改了DataGridRowHeader模板以使用MultiBinding来实现ValidationErrorTemplate可见性:

  <Style x:Key="DataGridRowHeaderStyle" TargetType="{x:Type DataGridRowHeader}">
<!--<Setter Property="Background" Value="{DynamicResource {ComponentResourceKey TypeInTargetAssembly=Brushes:BrushesLibrary1,
             ResourceId=HeaderBrush}}"/>-->
<Setter Property="Template">
  <Setter.Value>
    <ControlTemplate TargetType="{x:Type DataGridRowHeader}">
      <Grid>
        <Microsoft_Windows_Themes:DataGridHeaderBorder BorderBrush="{TemplateBinding BorderBrush}"
                          BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"
                          IsPressed="{TemplateBinding IsPressed}" IsHovered="{TemplateBinding IsMouseOver}"
                            IsSelected="{TemplateBinding IsRowSelected}" Orientation="Horizontal"
                            Padding="{TemplateBinding Padding}" SeparatorBrush="{TemplateBinding SeparatorBrush}"
                            SeparatorVisibility="{TemplateBinding SeparatorVisibility}">
          <StackPanel Orientation="Horizontal">
            <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"
                                                                Width="15"/>
            <Control SnapsToDevicePixels="false"
                                       Template="{Binding ValidationErrorTemplate, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}">
              <Control.Visibility>
              <MultiBinding Converter="{StaticResource ValidationConverter}">
                <Binding Path="(Validation.HasError)" RelativeSource="{RelativeSource AncestorType={x:Type DataGridRow}}"/>
                <Binding Path="DataContext.HasErrors" RelativeSource="{RelativeSource AncestorType={x:Type DataGridRow}}"/>
              </MultiBinding>
              </Control.Visibility>
              <!-- Original binding below -->
              <!--Visibility="{Binding (Validation.HasError), Converter={StaticResource bool2VisibilityConverter},
                     RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}">-->
            </Control>
          </StackPanel>
        </Microsoft_Windows_Themes:DataGridHeaderBorder>
        <Thumb x:Name="PART_TopHeaderGripper" Style="{StaticResource RowHeaderGripperStyle}" VerticalAlignment="Top"/>
        <Thumb x:Name="PART_BottomHeaderGripper" Style="{StaticResource RowHeaderGripperStyle}" VerticalAlignment="Bottom"/>
      </Grid>
    </ControlTemplate>
  </Setter.Value>
</Setter>

这取决于具有&#34; HasErrors&#34;的绑定对象。带变更通知的财产。在我的项目中,我确保通过在EndEdit项事件中为HasErrors引发PropertyChanged来更新HasErrors属性。

答案 4 :(得分:2)

我找到了此问题的根本原因。这与BindingExpressionBase失去对BindingGroup的引用的方式有关,因为只有BindingExpression才有责任删除其ValidationErrors

在DataGrid验证的情况下,它有多个来源可能会丢失参考:

  • 明确地,当可视树由DataGridCellDataGridCell.BuildVisualTree()重建时,属于该单元格的BindingExpressions中所有旧的BindingGroup被删除,然后Content属性更改为新值
  • 明确地,当Content的{​​{1}}属性被更改(通过DataGridCell或其他方式)时,旧版本上的所有绑定都将调用DataGridCell.BuildVisualTree()方法属性值,它也将在删除任何BindingExpressionBase.Detach()之前删除对BindingGroup的引用
  • 隐式地,因为往返于ValidationError的所有引用实际上都是BindingExpressionBase,即使上述所有情况都不会导致删除引用,而是在{{1 }}(WeakReference)中,基础TargetElement有可能返回BindingExpressionBase,并且属性访问器再次调用损坏的WeakReference方法

有了上述发现,现在也很清楚为什么对于null使用Detach()有时可以解决该问题。 Mode=TwoWay将变为只读状态,因此DataGridTextColumn的{​​{1}}属性将永远不会更改。

为此,我使用了附件的DataGridTextColumn编写了解决方法。

Content

然后将此属性与绑定绑定到DataGridCell的{​​{1}}属性。

DependencyProperty

答案 5 :(得分:1)

尝试从每个Binding元素中删除每个Mode=TwoWay的{​​{1}}。

答案 6 :(得分:1)

如果您看到越来越多的错误类似于Meleak,我很想知道您的错误集合是如何填充的。在Meleaks版本的问题中,他在解析无效数据后会看到三个错误(等等)。

在我的数据验证代码中,我删除了特定错误的先前实例,然后在每次数据更改时重新添加。作为参考,这是一个示例:

验证管道

#Region " Validation workers "

    Private m_validationErrors As New Dictionary(Of String, String)
    Private Sub AddError(ByVal ColName As String, ByVal Msg As String)
        If Not m_validationErrors.ContainsKey(ColName) Then
            m_validationErrors.Add(ColName, Msg)

        End If
    End Sub
    Private Sub RemoveError(ByVal ColName As String)
        If m_validationErrors.ContainsKey(ColName) Then
            m_validationErrors.Remove(ColName)
        End If
    End Sub


    Public ReadOnly Property [Error]() As String Implements System.ComponentModel.IDataErrorInfo.Error
        Get
            If m_validationErrors.Count > 0 Then
                Return "Shipment data is invalid"
            Else
                Return Nothing
            End If
        End Get
    End Property

    Default Public ReadOnly Property Item(ByVal columnName As String) As String Implements System.ComponentModel.IDataErrorInfo.Item
        Get
            If m_validationErrors.ContainsKey(columnName) Then
                Return m_validationErrors(columnName).ToString
            Else
                Return Nothing
            End If
        End Get
    End Property

#End Region

正在验证的属性

    Private Sub OnZIPChanged()
        Me.RemoveError("ZIP")
        If _ZIP Is Nothing OrElse _ZIP.Trim = "" Then
            Me.AddError("ZIP", "Please enter a ZIP Code")
        Else
            Select Case _ZIP.Length
                Case 5

                Case 10

                Case Else
                    Me.AddError("ZIP", "Please enter a ZIP Code")
            End Select
        End If
        OnPropertyChanged("CanShip")
    End Sub

因此,当运行属性Changed处理程序时,如果ValidationErrors字典中存在错误,则将其删除,然后检查该值,如果与要求不匹配,则会向字典添加错误。这有助于确保该实体验证错误字典中只存在任何错误的一个实例。

答案 7 :(得分:1)

我的解决方法是不使用Validation.Errors,而是使用DataGridRow.Item属性。如果DataGrid绑定到实现IDataErrorInfo接口的业务对象,则可以添加IsNotValid属性(或IsValid),并确保Error属性返回与该对象关联的所有错误。然后为DataGridRowHeader自定义默认样式:

<Style x:Key="{x:Type DataGridRowHeader}" TargetType="{x:Type DataGridRowHeader}">
    ...
    <Control SnapsToDevicePixels="false"
             Visibility="{Binding RelativeSource={RelativeSource 
                          AncestorType={x:Type DataGridRow}}, 
                          Path=Item.IsNotValid, Converter={StaticResource 
                          Bool2VisibilityConverter}}"
             Template="{Binding RelativeSource={RelativeSource 
                        AncestorType={x:Type DataGridRow}}, 
                        Path=ValidationErrorTemplate}" />

    ...
</Style>

同样在DataGridRow样式中自定义ValidationErrorTemplate,以便它显示来自DataGridRow.Item.Error proeprty的错误消息。

答案 8 :(得分:1)

就我而言,当我们使用DataGrid WPF3.5版本时,它运行良好。我们升级到4.0,然后停止重置。在搜索了SO,google等之后,我偶然发现了我的解决方案。 在DataGridTextColumn的Binding上设置 UpdateSourceTrigger = PropertyChanged 为我修复了它。

我刚刚意识到红色感叹号在设置为正确值时无法清除。

答案 9 :(得分:0)

我的情景是这样的:

  1. 模型实现 IDataErrorInfo
  2. 基于WPF DataGrid Practical Examples -Validation with IDataErrorInfo的自定义行验证规则,它使用IDataErrorInfo组合了Model中的所有错误。

    <DataGrid.RowValidationRules>
        <local:RowDataInfoValidationRule ValidationStep="UpdatedValue" />
    </DataGrid.RowValidationRules>
    
  3. 绑定中的
  4. ValidatesOnDataErrors=TrueValidatesOnExceptions=TrueNotifyOnValidationError=True(我开始时)

  5. 这导致多次访问我的验证引擎并最终导致我的DataGrid处于不一致状态(即使行有效,也会在行标题上显示错误通知)。

    解决方案是从绑定中删除开关(第3点)。

    我建议您仔细阅读Clearing a DataGrid row validation error

答案 10 :(得分:0)

我的解决方法是从每个datagrid列中的绑定声明中删除属性 UpdateSourceTrigger =“LostFocus”

答案 11 :(得分:0)

在我的情况下,我不得不从绑定定义中删除

UpdateSourceTrigger=PropertyChanged

对我而言,它适用于以下两种定义:

<DataGridTextColumn                                         
Header="Time, min" 
x:Name="uiDataGridTextColumnTime"
Width="Auto"                                            
CellStyle="{StaticResource ResourceKey=DataGridCellText}"                                            
IsReadOnly="False">
<DataGridTextColumn.Binding>
    <Binding Path="fTime" StringFormat="{}{0:0.00}">
        <Binding.ValidationRules>
            <Validation:CellDataInfoValidationRule ValidationStep="UpdatedValue"/>
        </Binding.ValidationRules>
    </Binding>
</DataGridTextColumn.Binding>

<DataGridTextColumn                                         
Header="Time, min" 
x:Name="uiDataGridTextColumnTime"
Width="Auto"                                            
CellStyle="{StaticResource ResourceKey=DataGridCellText}"     
Binding="{Binding fTime, StringFormat={}\{0:0.00\}, ValidatesOnDataErrors=True}" 
IsReadOnly="False">

验证:CellDataInfoValidationRule是自定义类&amp;得到它

public class CellDataInfoValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
        // obtain the bound business object
        BindingExpression expression = value as BindingExpression;
        IDataErrorInfo info = expression.DataItem as IDataErrorInfo;

        // determine the binding path
        string boundProperty = expression.ParentBinding.Path.Path;

        // obtain any errors relating to this bound property
        string error = info[boundProperty];
        if (!string.IsNullOrEmpty(error))
        {
            return new ValidationResult(false, error);
        }

        return ValidationResult.ValidResult;
    }
}

您的数据对象必须实现IDataErrorInfo

答案 12 :(得分:0)

我没有使用IDataErrorInfoINotifyDataErrorInfo,我的解决方案是将我的绑定从UpdateSourceTrigger="PropertyChanged"更改为UpdateSourceTrigger="LostFocus"这是唯一的

如果您在DataGrid列定义中使用ValidationRules,并且需要验证规则在属性更改时运行(在UI或属性中),请查看ValidatesOnTargetUpdated="True" <上的设置ValidationRule / p>

XAML示例:

<DataGridTextColumn Header="Name"
    CellStyle="{StaticResource DGCellStyle}"
    ElementStyle="{StaticResource DGTextColValidationStyle}"
    EditingElementStyle="{StaticResource DGTextColEditValidationStyle}">
    <DataGridTextColumn.Binding>
        <Binding Path="Name" UpdateSourceTrigger="LostFocus">
            <Binding.ValidationRules>
                <ValidationResource:YourValidationRule ValidationStep="UpdatedValue" ValidatesOnTargetUpdated="True" />
            </Binding.ValidationRules>
        </Binding>
    </DataGridTextColumn.Binding>
</DataGridTextColumn>

答案 13 :(得分:0)

好的,经过一些工作,改变了协同解决方案对我有用,这就是我实现它的方式:

    <Style x:Key="{x:Type DataGridRowHeader}" TargetType="{x:Type DataGridRowHeader}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <Control SnapsToDevicePixels="true"
                 Visibility="{Binding RelativeSource={RelativeSource 
                              AncestorType={x:Type DataGridRow}}, 
                              Path=Item.HasErrors, Converter={StaticResource 
                              BooleanToVisibilityConverter }}"
                 Template="{Binding RelativeSource={RelativeSource 
                            AncestorType={x:Type DataGridRow}}, 
                            Path=ValidationErrorTemplate}" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

不要忘记引用BooleanToVisibilityConverter:

    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>

只是行样式(还)看起来不如默认样式,我正在处理它。

编辑:Plz帮助

答案 14 :(得分:0)

我已经使用了这种取消RowValidationRules的技术,而是在viewmodel中使用属性验证。这需要静态变量和数据注释:

//uses Prism.MVVM for BindableBase and INotifyDataErrorInfo

private static int _xxStartNo;
private static int _xxEndNo;

// in property getter/setter
private int _startNo;
[CustomValidation(typeof(YourModel), "ValidateStartNoRange")]
public int StartNo
{
    get
       {
          _xxStartNo=_startNo;
          return _startNo;
       }
    set
       {
         .......... 
         ValidateProperty("StartNo") 
       }
}
.......

public static ValidationResult ValidateStartNoRange(int number)
{
   if(number > _xxEndNo) 
   {
       return ValidationResult("Start No must be less than End No.";
   }
   return ValidationResult.Success;
}       

答案 15 :(得分:0)

最初的问题来自2011年,而Datagrids Validation-System仍然存在许多问题,因此无法使用。我花了2天的时间来寻找解决方案,以完成以下工作:

  • 我的模型项实现INotifyDataErrorInfo和INotifyPropertyChanged
  • 它们在绑定到DataGrid的BindingList中
  • DataGrid应该显示来自用户输入以及来自不同来源的模型更改的验证错误
  • RowValidation-Error-mark应该显示是否有任何单元格具有验证错误,否则隐藏,无论用户当前是否正在编辑,提交或对行不执行任何操作
  • 无效的单元格应显示带有错误文本的工具提示
  • 没有错误或小故障

实现此行为的唯一方法是放弃RowValidation和CellValidation,而改用RowHeader和Styles。我从网络上的各种来源复制了以下代码。我尚未对此进行广泛的测试,但是乍看之下它看起来很有希望。

在DataGrids XAML中:

<DataGrid ... local:DataGridProps.ShowCellErrorBorder="False">
<DataGrid.Resources>
    <local:DataGridValidationConverter x:Key="DataGridValidationConverter" />
    <Style TargetType="TextBlock" x:Key="errTemplate">
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="true">
                <Setter Property="ToolTip"
                      Value="{Binding Path=(Validation.Errors)[0].ErrorContent}
                        RelativeSource={x:Static RelativeSource.Self}, "/>
                <Setter Property="Background" Value="LightSalmon"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</DataGrid.Resources>

<DataGrid.RowValidationErrorTemplate>
    <ControlTemplate>
            
    </ControlTemplate>
</DataGrid.RowValidationErrorTemplate>

<DataGrid.RowHeaderTemplate>
    <DataTemplate>
        <Grid Margin="0,-2,0,-2" 
              Visibility="{Binding Path=DataContext.HasErrors,
                RelativeSource={RelativeSource Mode=FindAncestor,
                  AncestorType={x:Type DataGridRow}},
                Converter={StaticResource DataGridValidationConverter},
                FallbackValue=Hidden}">
            <Ellipse StrokeThickness="0" Fill="Red"
                    Width="{Binding Path=FontSize,
                      RelativeSource={RelativeSource Mode=FindAncestor,
                        AncestorType={x:Type DataGridRow}}}"
                    Height="{Binding Path=FontSize,
                      RelativeSource={RelativeSource Mode=FindAncestor,
                        AncestorType={x:Type DataGridRow}}}" />
            <TextBlock Text="!" FontWeight="Bold" Foreground="White" HorizontalAlignment="Center"
                    FontSize="{Binding Path=FontSize,
                      RelativeSource={RelativeSource Mode=FindAncestor,
                        AncestorType={x:Type DataGridRow}}}" />               
        </Grid>
    </DataTemplate>
</DataGrid.RowHeaderTemplate>

<DataGrid.Columns>
    <DataGridTextColumn Header="Vorname" ElementStyle="{StaticResource errTemplate}"
          Binding="{Binding Path=Vorname,
             ValidatesOnNotifyDataErrors=True,
             NotifyOnValidationError=True}" />
    ...
</DataGrid.Columns>
</DataGrid>

DataGridValidationConverter:

public class DataGridValidationConverter : IValueConverter
{
       
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if ((bool)value)
            return Visibility.Visible;
        else
            return Visibility.Hidden;
    }

       
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

DataGridProps:

public class DataGridProps
{
public static readonly DependencyProperty ShowCellErrorBorderProperty = DependencyProperty.RegisterAttached(
            "ShowCellErrorBorder", typeof(bool), typeof(DataGridProps), new PropertyMetadata(true, ShowCellErrorBorderPropertyChangedCallback));

public static bool GetShowCellErrorBorder(DependencyObject element)
{
    return (bool)element.GetValue(ShowCellErrorBorderProperty);
}

public static void SetShowCellErrorBorder(DependencyObject element, bool value)
{
    element.SetValue(ShowCellErrorBorderProperty, value);
}

private static void ShowCellErrorBorderPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
    if (GetShowCellErrorBorder(dependencyObject)) return;
    var dg = dependencyObject as DataGrid;
    if (null != dg)
    {
        dg.Loaded += (sender, args) =>
        {
            var scrollView = dg.Template.FindName("DG_ScrollViewer", dg) as ScrollViewer;
            if (null == scrollView) return;
            var scrollContent = scrollView.Template.FindName("PART_ScrollContentPresenter", scrollView) as ScrollContentPresenter;
            if (null == scrollContent) return;
            scrollContent.AdornerLayer.Visibility = Visibility.Hidden;
        };
    }
}
}

模型的实现:

public Model()
{
    if (Vorname == null)
        Vorname = "";
    ...

    errorsByPropertyName = new Dictionary<string, List<string>>();
    this.PropertyChanged += Model_PropertyChanged;
    ForceRevalidation(null);
}

private string _vorname;
public string Vorname { get => _vorname; set => SetField(ref _vorname, value); }
...

public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
    if (EqualityComparer<T>.Default.Equals(field, value)) return false;
    field = value;
    OnPropertyChanged(propertyName);
    return true;
}

private Dictionary<string, List<string>> errorsByPropertyName;

public void ForceRevalidation(string propertyName)
{
    if (string.IsNullOrEmpty(propertyName))
    {
        foreach (PropertyInfo property in GetType().GetProperties())
        {
            ValidateProperty(property.Name);
        }
    }
    else
    {
        ValidateProperty(propertyName);
    }
}

protected virtual void OnErrorsChanged(string propertyName)
{
    ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
    OnPropertyChanged(nameof(HasErrors));
}

public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

public bool HasErrors => errorsByPropertyName.Any();

public System.Collections.IEnumerable GetErrors(string propertyName)
{
    if (propertyName == null)
        propertyName = "";
    return errorsByPropertyName.ContainsKey(propertyName) ? errorsByPropertyName[propertyName] : null;
}

private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    ValidateProperty(e.PropertyName);
}

protected virtual void ValidateProperty(string propertyName)
{
    if (propertyName == null)
        propertyName = "";

    ClearErrors(propertyName);

    switch (propertyName)
    {
        case nameof(Vorname):
            if (string.IsNullOrWhiteSpace(Vorname))
                AddError(propertyName, propertyName + " is empty");
            break;
        ...
        default:
            break;

    }
}

protected void AddError(string propertyName, string error)
{
    if (!errorsByPropertyName.ContainsKey(propertyName))
        errorsByPropertyName[propertyName] = new List<string>();

    if (!errorsByPropertyName[propertyName].Contains(error))
    {
        errorsByPropertyName[propertyName].Add(error);
        OnErrorsChanged(propertyName);
    }
}

protected void ClearErrors(string propertyName)
{
    if (errorsByPropertyName.ContainsKey(propertyName))
    {
        errorsByPropertyName.Remove(propertyName);
        OnErrorsChanged(propertyName);
    }
}

我从我的更大的Model-Base-Class创建了这个最小的示例,希望在这里我对这方面有所有重要的东西。

相关问题