Home > Software engineering >  Is it possible to change properties on the validation error template in WPF?
Is it possible to change properties on the validation error template in WPF?

Time:06-20

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

  • Related