Question:
There are two approaches I am familiar with to validate the input and issue an appropriate message to the user – throwing an exception in the setter and using the ExceptionValidationRule
and using the IDataError
interface.
The question is: can different ErrorTemplate
styles be applied depending on the type of exception?
I will give an example – there is a class describing an object, with fields A
, B
and C
Depending on the values of A
and B
field C
can be either required or optional. In the first case, the empty field C
is a critical error and the user cannot be given to save the object, in the second case, you just need to notify the user.
In fact, I want to apply different styles depending on whether the field is desired or required. Let's say for obligatory controls to highlight in red, and for desirable ones – in green. Is this possible, or will you have to come up with a different approach, without using inline validation?
Answer:
In general, the solution was found in the course of studying the structure of theValidation
class. Why I was looking for him for so long – I don't know, apparently I was looking in the wrong direction.
TheValidation
class has an Errors
collection that contains a description of the validation errors. So, each element of this collection has a ValidationError
type, which has the Exception
property we need. Now we can define a template based on its type.
Let me give you 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 properties of C
we depending on the condition threw two different exceptions. Now we need to handle this in the Validation.ErrorTemplate
. This is where ContentControl
and DataTemplate
come in DataTemplate
. 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 exception, the frame will be either cool or yellow.