tags:

views:

225

answers:

2

Hi,

I have a control template in one of my pages and i am assigning this template to my textbox's Validation.ErrorTemplate property. The following code would give you a better view.

<ControlTemplate x:Key="ValidationErrorTemplate">
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
                <AdornedElementPlaceholder/>
                <Image Name="ValidizorImage" Stretch="None" Source="validizor.gif" ToolTip="{Binding [0].ErrorContent}" ToolTipService.InitialShowDelay="0" ToolTipService.ShowDuration="60000"/>
            </StackPanel>
</ControlTemplate>

The above template sets the image at the end of the textbox which is having the error. This template is used as below.

<TextBox Grid.Column="5" Grid.Row="1" x:Name="txtemail" Grid.ColumnSpan="3" Margin="0,1,20,1" Validation.ErrorTemplate="{StaticResource ValidationErrorTemplate}"  />

My question here is

I want to move this control template outside of this page so that i can use it across the application.

I tried putting the exact same code of the control template in a user control say "ErrorUC"

<UserControl...>
    <Grid>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
            <AdornedElementPlaceholder/>
            <Image Name="ValidizorImage" Stretch="None" Source="validizor.gif" ToolTip="{Binding [0].ErrorContent}" ToolTipService.InitialShowDelay="0" ToolTipService.ShowDuration="60000"/>
        </StackPanel>
    </Grid>
</UserControl>

and used it as below

TextBox1.SetResourceReference
(System.Windows.Controls.Validation.ErrorTemplateProperty, new ErrorUC());

On running the above code i learnt that "AdornedElementPlaceholder" can be used only in templates and not in user controls. If i comment the same i am not getting the desired result.

Can anyone please help! Thanks in advance!

Regards,

Samar

A: 

The Validation.ErrorTemplate property expects a ControlTemplate and no UserControl. That's why your code is not working. You should better keep your "ValidationErrorTemplate" and put it in a shared ResourceDictionary which you can access everywhere in your application (or where you need it). For example, you could put it in your App.xaml and then reference it using a DynamicResource.


EDIT: OK, here we go with a more detailed explanation. Unless it is a requirement, I think you would better work with XAML instead of too much code loading ResourceDictionaries and assigning properties. You can easily achieve the desired behavior in XAML like this:

Open the file called "App.xaml" in your WPF application project. Visual Studio/Blend will create that file automatically for you. This file contains a section <Application.Resources>. Add your ControlTemplate to this section:

<Application.Resources>
    <ControlTemplate x:Key="ValidationErrorTemplate">
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
            <AdornedElementPlaceholder/>
            <Image Name="ValidizorImage" Stretch="None" Source="validizor.gif" ToolTip="{Binding [0].ErrorContent}" ToolTipService.InitialShowDelay="0" ToolTipService.ShowDuration="60000"/>
        </StackPanel>
    </ControlTemplate>
</Application.Resources>

Now, simply assign this error template to your controls using the Validation.ErrorTemplate property like this:

<TextBox ... Validation.ErrorTemplate="{DynamicResource ValidationErrorTemplate}" />

Of course, you must have a Binding with ValidationRules defined for the respective properties on the control (e.g. the Text property of a TextBox). In a simple app, this code works for me: The image is displayed if the validation fails.

I am not an expert in doing all this in code as I highly prefer XAML to define the UI. But as far as I can say, your code looks OK to me. Does the validation really fail? Check that by removing the Validation.ErrorTemplate. If your TextBox gets a red border, then it does fail - otherwise there might be an error in your validation logic?!

HTH, gehho.

gehho
hi hth,i tried your solution. Pls check this post for the same as i am unable to fit my query in the comment section.
samar
hi hth i got it by adding the following code in xaml against the textbox where i need the template to work.Validation.ErrorTemplate="{DynamicResource ValidationErrorTemplate}"But can we bring the above mentioned in code behind. Something similar toTextBox1.SetResourceReference(Validation.ErrorTemplateProperty, ct);mentioned above?? Please do let me know.
samar
As I said, I am no expert in doing this in code. According to MSDN, [SetResourceReference(...)](http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.setresourcereference.aspx) should be *similar* to `DynamicResource`, but they do not give any detail about the differences. Anyway, I think it should do the same for this scenario. Does your call `System.Windows.Application.Current.Resources["ValidationErrorTemplate"];` return any value, or is it `null`? If it is `null`, you should consider using `this.FindResource(...)` instead.
gehho
hi hth, your solution was pretty cool and got it through xaml. I also got it through code behind also through the following code. TextBox1.SetResourceReference(Validation.ErrorTemplateProperty, "ValidationErrorTemplate"); I was unnecessarily putting the resource in a control template and then using it. :) Thanks a million for your help, time and patiance. Regards, Samar
samar
You're welcome! :) I'm glad it works.
gehho
A: 

Hi HTH,

I tried your solution

a) I added dictionary.xaml in the project and added my control template to it as

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
    <ControlTemplate x:Key="ValidationErrorTemplate">
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
            <AdornedElementPlaceholder/>
            <Image Name="ValidizorImage" Stretch="None" Source="validizor.gif" ToolTip="{Binding [0].ErrorContent}" ToolTipService.InitialShowDelay="0" ToolTipService.ShowDuration="60000"/>
        </StackPanel>
    </ControlTemplate>
</ResourceDictionary>

b) I added this dictionary to my application resources as

Uri uri = new Uri("my dictionary uri", UriKind.RelativeOrAbsolute);

            ResourceDictionary dict = new ResourceDictionary();
            dict.Source = uri;
            Application.Current.Resources.MergedDictionaries.Add(dict);

c) I tried accessing the dictionary as

ControlTemplate ct = (ControlTemplate)System.Windows.Application.Current.Resources["ValidationErrorTemplate"];
TextBox1.SetResourceReference(Validation.ErrorTemplateProperty, ct);

Still my control template is not getting attached. I checked if the control template is there in the application resources and i found that indeed it is there i.e. the following line is giving me true

Application.Resources.Contains("ValidationErrorTemplate");

Am I missing out on something here??

Thanks,

Samar

samar
Please check the edits to my original answer.
gehho