2012-05-11 42 views
4

我有一个名为UniqueNameSolidWoodRule的简洁的ValidationRule来验证数据网格中的重复条目。Wpf datagrid validationrule唯一字段

下面的代码:

public class UniqueNameSolidWoodRule : ValidationRule 
{ 
    public CollectionViewSource CurrentCollection { get; set; } 

    public override ValidationResult Validate(object value, CultureInfo cultureInfo) 
    { 
     if (value != null) 
     { 
      ObservableCollection<SolidWood_VM> castedCollection = (ObservableCollection<SolidWood_VM>)CurrentCollection.Source; 

      foreach (SolidWood_VM swVM in castedCollection) 
      { 
       if (swVM.Designation == value.ToString()) 
       { 
        return new ValidationResult(false, ResourcesManager.Instance.GetString("DuplicatedRecord")); 
       } 
      } 
     } 

     return new ValidationResult(true, null); 
    } 
} 

而这里的XAML代码片段:

<DataGrid.Resources> 
     <CollectionViewSource x:Key="CurrentSolidWoodCollection" Source="{Binding Path=SolidWoods}" /> 
</DataGrid.Resources> 

<DataGridTextColumn x:Name="Column2" Header="{x:Static p:Resources.Designation}" Width="auto"> 
     <DataGridTextColumn.Binding> 
      <Binding Path="Designation" ValidatesOnDataErrors="True" UpdateSourceTrigger="LostFocus"> 
       <Binding.ValidationRules> 
         <my:UniqueNameSolidWoodRule CurrentCollection="{StaticResource CurrentSolidWoodCollection}"/> 
        </Binding.ValidationRules> 
      </Binding> 
     </DataGridTextColumn.Binding> 
    </DataGridTextColumn> 

我的问题是,有时比较规则与自己行的值。我怎么能阻止呢?在我看来,我需要一个row.index属性与要比较的值相关联,但不幸的是我无法想出一个办法来实现这一点。

回答

12

我终于得到了工作!

这里的解决方案:

在XAML添加以下ValidationStep:

<my:UniqueNameSolidWoodRule CurrentCollection="{StaticResource CurrentSolidWoodCollection}" ValidationStep="CommittedValue"/> 

这样,我得到的,而不是一个字符串作为覆盖验证方法的第一个参数BindingExpression对象,这给了我更多关于记录验证的信息,比如HashCode我可以用来检查我是否在比较同一个对象。

下面是更新验证方法:

public class UniqueNameSolidWoodRule : ValidationRule 
{ 
    public CollectionViewSource CurrentCollection { get; set; } 

    public override ValidationResult Validate(object value, CultureInfo cultureInfo) 
    { 
     if (value != null) 
     { 
      ObservableCollection<SolidWood_VM> castedCollection = (ObservableCollection<SolidWood_VM>)CurrentCollection.Source; 

      SolidWood_VM curValue = (SolidWood_VM)((BindingExpression)value).DataItem; 

      foreach (SolidWood_VM swVM in castedCollection) 
      { 
       if (curValue.GetHashCode() != swVM.GetHashCode() && swVM.Designation == curValue.Designation.ToString()) 
       { 
        return new ValidationResult(false, ResourcesManager.Instance.GetString("DuplicatedRecord")); 
       } 
      } 
     } 

     return new ValidationResult(true, null); 
    } 
}