2011-07-06 40 views
3

我与DataGrid的一个简单的WPF应用程序wchich被绑定到该列表以Employee对象:WPF Datagrid的新行验证

public class Employee 
{ 
    private string _name; 

    public int Id { get; set; } 


    public string Name 
    { 
     get { return _name; } 
     set 
     { 
      if (String.IsNullOrEmpty(value)) 
       throw new ApplicationException("Name cannot be empty. Please specify the name."); 
      _name = value; 
     } 
    } 

正如你所看到的,我想阻止不设置Name属性创建员工。 所以,我做了一个验证规则:

public class StringValidationRule : ValidationRule 
{ 
    public override ValidationResult Validate(object value, CultureInfo cultureInfo) 
    { 
     string str = value as string; 
     if (String.IsNullOrEmpty(str)) 
      return new ValidationResult(false, "This field cannot be empty"); 
     else 
      return new ValidationResult(true, null); 
    } 
} 

的名称字段的XAML如下:

<DataGridTextColumn Header="Name" 
           ElementStyle="{StaticResource datagridElStyle}" > 
       <DataGridTextColumn.Binding> 
        <Binding Path="Name" Mode="TwoWay" NotifyOnValidationError="True" ValidatesOnExceptions="True" UpdateSourceTrigger="PropertyChanged" > 
         <Binding.ValidationRules> 
          <emp:StringValidationRule/> 
         </Binding.ValidationRules> 
        </Binding> 
       </DataGridTextColumn.Binding> 
      </DataGridTextColumn> 

如果我尝试编辑在DataGrid中现有员工行的名称,将其设置为空字符串,datagrid标记错误的字段,不允许保存行。这是正确的行为。

但是,如果我创建一个新行并在键盘上按回车键,这个新行创建_name设置为NULL,验证不起作用。我想这是因为DataGrid调用新行对象的默认构造函数并将_name字段设置为NULL。

什么是验证新行的正确方法?

回答

2

您可以在Employee对象上实施IDataError。这here有一个很好的网页。

+0

谢谢,我会研究它,并张贴在这里,如果我找到任何解决方案。但验证编辑工作正常,我认为可能有一些简单的方法来验证新行,因为这是一项非常普遍的任务。 – MyUserName

+0

是的,Employee类中的IDataError实现有所帮助。我在这里找到了一个很好的例子:http://www.codeproject.com/KB/WPF/WPFDataGridExamples.aspx#errorinfo – MyUserName

+0

@MyUserName:很高兴帮助。 :) –

0

我实际上遇到了同样的问题,但是因为我一直在使用MVC数据注释,如Karl Shifflett所示:http://bit.ly/18NCpJU。我最初认为这是一个好主意,但我现在意识到,微软不打算包含MVC数据注释,因为这些注释似乎更适合提交表单,但不是数据持续存在并且可以编辑的应用程序会议,但我离题..

这是我做临时解决方法。长期的解决方案将实施IDataError:

// BusinessEntityBase is what allows us to 
// use MVC Data Annotations (http://bit.ly/18NCpJU) 
public class MyModel : BusinessEntityBase 
{ 
    private string _name; 
    private List<Action> _validationQueue = new List<Action>(); 
    private Timer _timer = new Timer { Interval = 500 }; 

    [Required(AllowEmptyStrings = false)] 
    public string Name 
    { 
     get 
     { 
      return this._name; 
     } 
     set 
     { 
      var currentValue = this._name; 
      this._name = value; 
      base.RaisePropertyChanged("Name"); 

      this.AddValidationAction("Name", currentValue, value ); 
     } 
    } 

    private void AddValidationAction<T>(string Name, T currentValue, T newValue) 
    { 
     Action validationAction = 
      () => 
       base.SetPropertyValue(Name, ref currentValue, newValue); 
     _validationQueue.Add(validationAction); 
     this._timer.Enabled = true; 
    } 

    private void ProcessValidationQueue(object sender, ElapsedEventArgs e) 
    { 
     if(_validationQueue.Count > 0) 
     { 
      while (_validationQueue.Count > 0) 
      { 
       _validationQueue[0].Invoke(); 
       _validationQueue.RemoveAt(0); 
      } 
     } 

     this._timer.Enabled = false; 
    } 

    public MyModel() 
    { 
     _timer.Enabled = false; 
     _timer.Elapsed += this.ProcessValidationQueue; 
     _timer.Start(); 
    } 
}