Setting Validation error template from code in WPF
Asked Answered
S

4

14

I have a TextBox in my WPF app. I have defined a ControlTemplate for validation error as follows:

<ControlTemplate x:Key="validationTemplate">
    <DockPanel LastChildFill="True">
         <TextBlock DockPanel.Dock="Bottom"  Text="Invalid Input: "></TextBlock>
                 <AdornedElementPlaceholder />
    </DockPanel>
</ControlTemplate>

My TextBox is as follows :

<TextBox Validation.ErrorTemplate="{StaticResource validationTemplate}">                                              
    <TextBox.Text>
        <Binding Path="TEXT1" ValidatesOnDataErrors="True" validatesOnExceptions="True">
         </Binding>
    </TextBox.Text>
</TextBox>

Now if my TextBox is added ValidationRule and then I validate there, the error template applies correctly. But I cant do that because of some other problem.

So I have to validate the content of TextBox in PreviewLostKeyboardFocus. I am validating the TextBox. Now I want to set the error template for the TextBox in code behind but I am unable to do it !!

I tried this but it does not work as intented::

private void blockTextBox_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
    {
        TextBox txtBox = sender as TextBox;
        txtBox.Template = this.FindResource("validationTemplate") as ControlTemplate;

        //this behaves strange; it removes the TextBox and places the ErrorTemplate. 
       //I want it to behave like the way WPF does internally wherein it places 
       //the error template around TExtBox
    }

Question 1: I want to know how to add the error template to TextBox

Question 2: I want to know how do I set the error message of the control template from code. Like for example, I want to change the default error message "Invalid Input: " to "Invalid Input: Please enter correct input".

I want to do the above mentioned things in code behind only !!!!

EDIT 1:

The problem is how do I set from code behind Validation.HasError as true because I am not using any Validator. (or what should I set from code behind that ValidationTemplate gets applied ?? ))

EDIT 2:

I am doing XML binding so there is no way I can implement IDataErrorInfo !! I want to achieve this from code behind only!! Is there a way to set Validation.HasError from code behind ??

Sheley answered 25/11, 2010 at 5:3 Comment(0)
B
24

To set "Validation.HasError" in code behind you can use the Validation.MarkInvalid method

private void blockTextBox_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) 
{ 
    TextBox txtBox = sender as TextBox;
    //...
    BindingExpression bindingExpression =
        BindingOperations.GetBindingExpression(txtBox, TextBox.TextProperty);

    BindingExpressionBase bindingExpressionBase = 
        BindingOperations.GetBindingExpressionBase(txtBox, TextBox.TextProperty);

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

    Validation.MarkInvalid(bindingExpressionBase, validationError);
}

To unset the value you use

Validation.ClearInvalid
Billhead answered 26/11, 2010 at 17:20 Comment(0)
S
5

Thanks to for the wonderful link he suggested me.My code goes somewhat this way

String errorMessage = GetFormattedErrorMessage(toolTip.Range, range);
ValidationError validationError = new ValidationError(new DummyValidator(),
txtBox.GetBindingExpression(TextBox.TextProperty));
Validation.MarkInvalid(txtBox.GetBindingExpression(TextBox.TextProperty), validationError);
validationError.ErrorContent = errorMessage;
Validation.SetErrorTemplate(txtBox, GetErrorTemplate(errorMessage));
Sheley answered 1/12, 2010 at 8:20 Comment(0)
D
4
Validation.SetErrorTemplate(txtBox, this.FindResource("validationTemplate") as ControlTemplate);
Dib answered 25/11, 2010 at 9:2 Comment(6)
For your Question# 2, you can dynamically create a ControlTemplate with proper error message and assign it to a Control.Dib
@Dib :: But the problem is how do I set from code behind Validation.HasError as true because I am not using any Validator.Sheley
Use IDataErrorInfo (msdn.microsoft.com/en-us/library/…) interface to mark the object that is bound to this control as invalid.Dib
@Dib : I am doing XML binding so there is no way I can implement IDataErrorInfo !! Is there a way to set Validation.HasError from code behind ??Sheley
I am not sure about this but did you try something like following : textBox1.SetValue(Validation.HasErrorProperty, true);?Dib
@Dib : It doesnot work !! I get this exception {'HasError' property was registered as read-only and cannot be modified without an authorization key."} :(Sheley
L
1

For your first question. You can set the ErrorTemplate from code behind like.

    public MainWindow()
    {
        InitializeComponent();

        var template = this.FindResource("validationTemplate") as ControlTemplate;
        Validation.SetErrorTemplate(this.textBox1, template);
     }


Edit: For your second question. Please refer the following sample. sites.google.com/site/html5tutorials/ValidationErrorText.zip

Linnell answered 25/11, 2010 at 9:5 Comment(4)
: But the problem is how do I set from code behind Validation.HasError as true because I am not using any Validator.Sheley
You have to create ValidationRule. Any specific reason for not creating ValidationRule?Linnell
Yes I cant use validation rule because of so many constraints I have!! Its a big project and I have to do it this way :( Please do u know how can I set the errorproperty on TextBox?Sheley
Least case, You need create validation rule. Check this link whether this helps wpftutorial.net/ValidationErrorByCode.html But, the error property is not meant to set directly!Linnell

© 2022 - 2024 — McMap. All rights reserved.