In general, the solution was found during the study of the structure of the class Validation
. Why I was looking for him for so long - I don’t know, I’ve looked at the wrong place.
The Validation
class has an Errors
collection that contains a description of validation errors. So here each element of this collection has a type ValidationError
, which has the Exception
property we need. Now we can, based on its type, define a pattern.
I will give an example. Maybe someone will come in handy.
There is a simple class:
public class SomeClass { public int A { get; set; } public int B { get; set; } private int _c; public int C { get { return _c; } set { // Вот тут мы и будем в зависимости от состояния других полей генерировать разные исключения if (A == 0 && B == 0 && value == 0) throw new ArgumentMandatoryException("Поле является обязательным к заполнению"); if ((A != 0 || B != 0) && value == 0) throw new ArgumentDesiredException("Поле является желательным к заполнению"); _c = value; } } }
As you can see in the setter property C
, depending on the condition, we threw two different exceptions. Now we need to handle this in the Validation.ErrorTemplate
template. This is where ContentControl
and DataTemplate
help us. We get something like this:
<DataTemplate DataType="{x:Type my:ArgumentMandatoryException}"> <Border BorderBrush="Red" BorderThickness="1"/> </DataTemplate> <DataTemplate DataType="{x:Type my:ArgumentDesiredException}"> <Border BorderBrush="Green" BorderThickness="1"/> </DataTemplate> <Style x:Key="errorTemplate" TargetType="Control"> <Setter Property="Validation.ErrorTemplate"> <Setter.Value> <ControlTemplate> <Grid> <ContentControl Content="{Binding ElementName=myControl, Path=AdornedElement.(Validation.Errors)[0].Exception}"></ContentControl> <AdornedElementPlaceholder Name="myControl" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>
Now, depending on the type of exclusion, the frame will be either cool or yellow.