我使用DataGrid创建了一个简单的WPF应用程序,并将其绑定到带有Employee对象的List:
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属性的Employees。 所以,我做了一个验证规则:
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 for Name字段如下:
<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会标记错误的字段,并且不允许保存行。这是正确的行为。
但是如果我创建一个新行并按下键盘上的Enter键,则会在_name设置为NULL的情况下创建此新行,并且验证不起作用。我想这是因为DataGrid为新行对象调用默认构造函数并将_name字段设置为NULL。
验证新行的正确方法是什么?
答案 0 :(得分:3)
您可以在IDataError
对象上实施Employee
。这个here有一个很好的页面。
答案 1 :(得分:0)
我实际上遇到了同样的问题,但因为我一直在使用Karl Shifflett所示的MVC数据注释: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();
}
}