I have a user control that has a textbox where its text property is bound to a dependency property called SelectedValue. When the user enters text, that value is validated against another DP called ItemsSource to see if it in there. If not, I throws an error. Everything works - the TB in the UC has the default red box around it when there is an error.
But I would like the user to be able to specify a ControlTemplate in XAML when creating an instance of the UC. So I thought I could create another DP of type ControlTemplate and they could bind to. This seems to work but how do I actually implement that in XAML? If it do something like:
Validation.ErrorTemplate="{Binding ValidationTemplate}"
it throws an error saying "'ErrorTemplate' property cannot be data-bound.". Below are the relevant parts of the code:
<Canvas DataContext="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}">
....
<TextBox x:Name="ValueTextBox"
TextWrapping="NoWrap"
GotFocus="_ValueTextBox_GotFocus"
Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type Canvas}}, Path=ActualWidth}"
Height="{Binding RelativeSource={RelativeSource AncestorType={x:Type Canvas}}, Path=ActualHeight}"
----->Validation.ErrorTemplate="{Binding ValidationTemplate}"<-----
>
<TextBox.Resources>
<CollectionViewSource x:Key="UniqueNamesList" Source="{Binding ItemsSource}" />
</TextBox.Resources>
<TextBox.Text>
<Binding Path="SelectedValue" >
<Binding.ValidationRules>
<l:InListValidator ValidationStep="RawProposedValue"
IgnoreCase="True"
UniqueNames="{StaticResource UniqueNamesList}" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
....
</Canvas>
and the DP itself:
public object ValidationTemplate
{
get { return (ControlTemplate)GetValue(ValidationTemplateProperty); }
set { SetValue(ValidationTemplateProperty, value); }
}
public static readonly DependencyProperty ValidationTemplateProperty =
DependencyProperty.Register("ValidationTemplate"
, typeof(ControlTemplate)
, typeof(AutoCompleteComboBox)
, new FrameworkPropertyMetadata(new ControlTemplate()));
Thank for any help.
Ernie
Update:
Thanks Guys. I actually tried both Adi and Nit's responses. Both worked but Adi was closer to what I was looking for with not having to define a template local to the User Control. Nit's actually runs even if I do not actually create the template and just add the binding but the designer gives an error. I did have to tweak your code a bit Adi to set it on the TextBox itself:
public ControlTemplate ValidationTemplate
{
get { return (ControlTemplate)GetValue(ValidationTemplateProperty); }
set { SetValue(ValidationTemplateProperty, value); }
}
public static readonly DependencyProperty ValidationTemplateProperty =
DependencyProperty.Register("ValidationTemplate"
, typeof(ControlTemplate)
, typeof(AutoCompleteComboBox)
, new FrameworkPropertyMetadata(new ControlTemplate(), OnValidationTemplateChanged));
private static void OnValidationTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue != null)
{
AutoCompleteComboBox control = (AutoCompleteComboBox)d;
Validation.SetErrorTemplate(control.ValueTextBox, (ControlTemplate)e.NewValue);
}
}
Thanks!
Looking at the Validation.ErrorTemplate MSDN page, you can see that it has the IsNotDataBindable metadata property set to true, so unfortunately you can't data bind to that property.
I believe you can still handle your dependency property's OnChanged event to set that property yourself with Validation.SetErrorTemplate():
public static readonly DependencyProperty ValidationTemplateProperty =
DependencyProperty.Register("ValidationTemplate",
typeof(ControlTemplate),
typeof(AutoCompleteComboBox),
new FrameworkPropertyMetadata(new ControlTemplate(), OnValidationTemplateChanged));
private static void OnValidationTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Validation.SetErrorTemplate(d, (ControlTemplate)e.NewValue);
}
As far as I know you cannot do what you want with Binding. ErrorTemplate can be used with StaticResource.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With