Search code examples
c#wpfxamladornererrortemplate

TextBox with Error Template with code


I'm trying to add some textbox to a form by code, not XAML. And using Error Validation. I have the following code:

SearchTextBox stb = new SearchTextBox()
{
    Name = "stbRelatorio_" + id
};

// Create a new Binding.
Binding bindingStb = new Binding();
bindingStb.Source = model;
bindingStb.Path = new PropertyPath("ReportFile[" + id + "]");
stb.SetBinding(SearchTextBox.FileNameProprety, bindingStb);

BindingExpression bindingExpression =
    BindingOperations.GetBindingExpression(stb, SearchTextBox.FileNameProprety);

BindingExpressionBase bindingExpressionBase =
    BindingOperations.GetBindingExpressionBase(stb, SearchTextBox.FileNameProprety);

ValidationError validationError =
    new ValidationError(new ExceptionValidationRule(), bindingExpression);

Validation.MarkInvalid(bindingExpressionBase, validationError);

ControlTemplate ct = this.Resources["validationErrorTemplate"] as ControlTemplate;

When I do this, I get the default behavior when there's no text inserted (that's my error case). The red box around the text box. What I want now is to use a custom Adorner Layout and I build it on XAML

<ControlTemplate x:Name="validationErrorTemplate" x:Key="validationErrorTemplate">
    <DockPanel>
        <StackPanel Orientation="Horizontal" DockPanel.Dock="Top">
            <Grid Width="12" Height="12">
                <Ellipse Width="12" Height="12" 
                    Fill="Red" HorizontalAlignment="Center" 
                    VerticalAlignment="Center"></Ellipse>
                <TextBlock Foreground="White" FontWeight="Heavy" 
                    FontSize="8" HorizontalAlignment="Center" VerticalAlignment="Center" TextAlignment="Center"
                    ToolTip="{Binding ElementName=ErrorAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
                    X
                </TextBlock>
            </Grid>
            <TextBlock Foreground="Red" FontWeight="12" Margin="2,0,0,2" 
                   Text="{Binding ElementName=ErrorAdorner, 
                   Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
            </TextBlock>
        </StackPanel>
        <AdornedElementPlaceholder x:Name="ErrorAdorner" />
    </DockPanel>
</ControlTemplate>

But when I try to set the ErrorTemplate:

Validation.SetErrorTemplate(stb, ct);

I don't get any error validation, not even the default template.

Am I missing something?


Solution

  • when you do

    ControlTemplate ct = this.Resources["validationErrorTemplate"] as ControlTemplate;
    Validation.SetErrorTemplate(stb, ct);
    

    and there is no even default error template, it is likely that ct is null

    make sure that "validationErrorTemplate" is stored in Window (this) resources. if template stored somewhere in resources, it can found by FindResource method

    ControlTemplate ct = stb.FindResource("validationErrorTemplate") as ControlTemplate;
    Validation.SetErrorTemplate(stb, ct);