C# WPF MVVM Datagrid单元验证错误行为问题:为什么删除我的值?

C# WPF MVVM Datagrid单元验证错误行为问题:为什么删除我的值?,c#,wpf,mvvm,wpfdatagrid,C#,Wpf,Mvvm,Wpfdatagrid,我的问题是DataGrid中验证错误的行为。它根据我的模型对象的属性进行验证,并显示正确的消息,但只要我选择其他行,验证就会与原始值一起消失 在下面的示例.gif中,我删除了名称(backspace),按enter键(获取验证消息),然后单击另一行。每当所选行发生更改时,我希望a)验证错误保持不变,或b)返回原始值,但该行保持空白,验证错误消失,直到我双击该行。双击后,返回原始值 我更希望验证错误持续存在,但此时我将采用这两种方法中的任何一种 以下是datagrid文本块样式: <

我的问题是DataGrid中验证错误的行为。它根据我的模型对象的属性进行验证,并显示正确的消息,但只要我选择其他行,验证就会与原始值一起消失

在下面的示例.gif中,我删除了名称(backspace),按enter键(获取验证消息),然后单击另一行。每当所选行发生更改时,我希望a)验证错误保持不变,或b)返回原始值,但该行保持空白,验证错误消失,直到我双击该行。双击后,返回原始值

我更希望验证错误持续存在,但此时我将采用这两种方法中的任何一种

以下是datagrid文本块样式:

    <Style x:Key="datagridElemStyle" TargetType="{x:Type TextBlock}">
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="True">
                <Setter Property="Background" Value="Yellow" />
                <Setter Property="ToolTip" 
                        Value="{Binding RelativeSource={RelativeSource Self}, 
                        Path=(Validation.Errors)[0].ErrorContent}"/>
            </Trigger>
        </Style.Triggers>
    </Style>
最后,这是我的模型(不相关的部分省略):


谢谢您的时间。

数据网格验证可能非常烦人。当
DataGridTextColumn
开始编辑时,绑定的实际值将恢复,这就是为什么在进入编辑模式时会看到还原

您基本上需要通过处理DataGrid的
BeginingEdit
事件来停止该调用

   <DataGrid AutoGenerateColumns="False" BeginningEdit="dg_BeginningEdit">

仅供参考:您的绑定在
LostFocus
上更新。如果将来更新
PropertyChanged
,此解决方案可能无法正常工作,因为它会更改操作顺序

这似乎没有任何效果,至少在我上面发布的行为方面是如此。@Chris这很奇怪,因为我复制了你的行为,并用这个修复了它。我想知道是否还有什么东西触发了恢复。您使用的是什么.NET framework?再仔细研究一下,只要在该行上切换IsSelected属性,就会感觉到错误被删除了。在我再次选择它之前,它一直无效。选择该行后,验证错误将清除,但该行不会“刷新”,因此它会一直显示一个空字段。
public class PointVM : INotifyPropertyChanged
{
    public Point DataContext { get; set; }
    public string Name
    {
        get { return DataContext.Name; }
        set
        {
            if (value != DataContext.Name)
            {
                DataContext.Name = value;
                OnPropertyChanged(new PropertyChangedEventArgs("Name"));
            }
        }
    }
public abstract class Point
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            string trimmedVal = value.Trim();
            #region Validation
            if (string.IsNullOrEmpty(trimmedVal))
                throw new Exception("Name cannot be empty.");

            if (Regex.IsMatch(trimmedVal, @"[^A-Za-z0-9\-_ ]$"))
                throw new Exception("Invalid character in name.");

            if (trimmedVal.Length > 64)
               throw new Exception("Name is too long.");

            if ((from p in PointList
                 where p.Name.Equals(trimmedVal, StringComparison.OrdinalIgnoreCase)
                 select p).Count() > 0)
                throw new Exception("Name is already used.");
            #endregion
            _name = trimmedVal;
        }
    }
   <DataGrid AutoGenerateColumns="False" BeginningEdit="dg_BeginningEdit">
   private void dg_BeginningEdit(object sender, DataGridBeginningEditEventArgs e)
   {
       e.EditingEventArgs.Handled = true;
   }