I’ve been working on a small WPF project that requires some business rule validation. I thought this would be relatively simple but proved to be slightly more complicated than expected. At the end of the day, I found two relatively simple ways to perform the validation.
The first is to simply bind ComboBox.Selected item to a property and do the validation in the set block.
private MyDataObject _someData;
public MyDataObject SomeData
{
get
{
return _ someData;
}
set
{
_ someData = value;
if (value == null || string.IsNullOrEmpty(value.MyProperty))
throw new ApplicationException("SomeData is required");
}
}
Then, in the XAML, you just need to hook it up to treat exceptions as validation errors.
<ComboBox.SelectedItem>
<Binding Path="SomeData" ElementName="Window">
<Binding.ValidationRules>
<ExceptionValidationRule />
</Binding.ValidationRules>
</Binding>
</ComboBox.SelectedItem>
The second method gives more flexibility but requires the creation of a custom ValidationRule class.
public class MyCustomValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
if (value is MyDataObject)
{
var myDataObj = (MyDataObject)value;
if (myDataObj.CheckCustomBusinessRules())
return new ValidationResult(true, null);
}
return new ValidationResult(false, "Invalid selection!");
}
}
And then you hook up the validation rules to use the new custom class.
<ComboBox.SelectedItem>
<Binding Path="SomeData" ElementName="Window">
<Binding.ValidationRules>
<local:PersonValidation />
</Binding.ValidationRules>
</Binding>
</ComboBox.SelectedItem>
(Note that the “local” prefix requires an additional namespace at the top of your XAML file, xmlns:local=”clr-namespace:MyNamespace”)
One last tip that threw me off for a bit is that I was missing x:Name=”Window” in my Window tag at the top of my XAML; this caused the ComboBox’s SelectedItem to not bind properly and the validation rules consequently didn’t work.
Like this:
Like Loading...