I have a ViewModel that represents multiple options and implements IDataErrorInfo. This ViewModel is only valid if at least one of these options is selected. It is bound to a ContentControl. A DataTemplate is used to visualize the ViewModel as a GroupBox containing an ItemsControl. Another DataTemplate visualizes each option as a CheckBox.
What do I have to do, to make the ContentControl work together with IDataErrorInfo and check the validity when a check box is checked or unchecked?
Some code:
Binding:
<ContentControl Content="{Binding GeneralInvoiceTypes, ValidatesOnDataErrors=True}"
Margin="0,0,5,0" />
Data templates:
<DataTemplate DataType="{x:Type ViewModels:MultipleOptionsViewModel}">
<GroupBox Header="{Binding Title}">
<ItemsControl ItemsSource="{Binding Options}" />
</GroupBox>
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModels:OptionViewModel}">
<CheckBox IsChecked="{Binding IsChecked}"
Content="{Binding Name}"
Margin="6,3,3,0" />
</DataTemplate>
Style:
<Style TargetType="{x:Type ContentControl}">
<Style.Triggers>
<Trigger Property="Validation.HasError"
Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}" />
</Trigger>
</Style.Triggers>
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="90*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Border BorderBrush="Red"
BorderThickness="1"
CornerRadius="2.75"
Grid.Column="0">
<AdornedElementPlaceholder Grid.Column="0" />
</Border>
<TextBlock Foreground="Red"
Grid.Column="1"
Margin="0"
FontSize="12"
VerticalAlignment="Center"
HorizontalAlignment="Left"
x:Name="txtError">
*
</TextBlock>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Based on the answers given, I solved it like this:
Change the
DataTemplateof theMultipleOptionsViewModelto bind theOptionsproperty withValidatesOnDataErrors=True:Change the error style to target
ItemsControlinstead ofContentControl.MultipleOptionsViewModelraises a PropertyChanged for"Options"when one of the child options is checked or uncheckedMultipleOptionsViewModelreacts to the column"Options"in its implementation ifIDataErrorInfo.Item, i.e. in its indexer.This solution has the benefit, that it uses the default behavior of
IDataErrorInfo, i.e. the consumer of this ViewModel doesn’t need handle it any special.I know that this solution is not 100% equivalent to that I asked about in the question – the error template is now displayed inside the group box instead of around it, but that’s something I can live with.