I'm using the Validation.ErrorTemplate property in my XAML view to display an icon next to any invalid control.
For one particular control in my view, I need to set the icon in a slightly different position. Is it possible for me to use the same control template, but somehow update the Margin
property for a certain control?
Here's my (abridged) code:
<UserControl>
<UserControl.Resources>
<ControlTemplate x:Key="ValidationTemplate" TargetType="Control">
<DockPanel>
<Grid
DockPanel.Dock="Right"
Height="16"
Margin="10,0,0,0"
VerticalAlignment="Center"
Width="16">
<Image
AutomationProperties.AutomationId="_validationIcon"
Source="{x:Static icons:Icons.ValidationIcon}"
ToolTip="{Binding Path=ErrorContent}" />
</Grid>
<AdornedElementPlaceholder />
</DockPanel>
</ControlTemplate>
<ItemsControl Validation.ErrorTemplate="{StaticResource ValidationTemplate}" />
</UserControl>
The only way I've managed to achieve what I need is to create a new ControlTemplate
just for the control that requires a different icon placement. I would rather reuse my original control template if possible.
CodePudding user response:
I had exactly same requirement in my old project. I solved it using an attached dependency property:
public static class ErrorTemplateProperties
{
public static readonly DependencyProperty ErrorMarginProperty = DependencyProperty.RegisterAttached
(
"ErrorMargin",
typeof(Thickness),
typeof(ErrorTemplateProperties),
new FrameworkPropertyMetadata(new Thickness(10,0,0,0))
);
public static Thickness GetErrorMargin(DependencyObject obj)
{
return (Thickness)obj.GetValue(ErrorMarginProperty);
}
public static void SetErrorMargin(DependencyObject obj, Thickness value)
{
obj.SetValue(ErrorMarginProperty, value);
}
}
add it to ValidationTemplate:
<ControlTemplate x:Key="ValidationTemplate" TargetType="Control">
<DockPanel>
<Grid
DockPanel.Dock="Right"
Margin="{Binding Path=AdornedElement.(local:ErrorTemplateProperties.ErrorMargin), ElementName=ui}"
Height="16"
VerticalAlignment="Center"
Width="16">
<Image
AutomationProperties.AutomationId="_validationIcon"
Source="{x:Static icons:Icons.ValidationIcon}"
ToolTip="{Binding Path=ErrorContent}" />
</Grid>
<AdornedElementPlaceholder x:Name="ui"/>
</DockPanel>
</ControlTemplate>
and then optionally change on required ui elements:
<ItemsControl helpers:ErrorTemplateProperties.ErrorMargin="0,0,0,0"
Validation.ErrorTemplate="{StaticResource ValidationTemplate}" />
I also found a workaround with DynamicResources but attached DP are more flexible and laconic in my opinion