Wpf datagrid validationrule for unique field

I have a suclassed ValidationRule named UniqueNameSolidWoodRule to check for duplicate records in a datagrid.

Here is the code:

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); } } 

And here is the XAML fragment:

 <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> 

My problem is that sometimes this rule compares the value with its own string. How could I prevent this? It seems to me that I need the row.index property associated with the value for comparison, but, unfortunately, I cannot figure out how to do this.

+4
source share
1 answer

I finally got a job!

Here's the solution:

In XAML, I added the following ValidationStep:

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

Thus, I get a BindingExpression object instead of a string as the first parameter of the overridden Validate method, which gives me much more information about the record to check, for example, HashCode . I can use to check if I am comparing the same object.

Here's the updated Validate method:

 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); } } 
+12
source

Source: https://habr.com/ru/post/1411934/


All Articles