I've got a suclassed ValidationRule named UniqueNameSolidWoodRule to validate for duplicate entries in a datagrid.
Here's 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's the XAML snippet:
<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 row. How could I prevent this? It seems to me that I need a row.index property associated with the value to compare, but unfortunnally I can't figure a way out to achieve this.
I finally got things working!
Here's the solution:
In the XAML I added the following ValidationStep:
<my:UniqueNameSolidWoodRule CurrentCollection="{StaticResource CurrentSolidWoodCollection}" ValidationStep="CommittedValue"/>
This way I'm getting 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 validate like the HashCode I can use to check if I'm 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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With