我有一个用户控件,其文本框的text属性绑定到名为SelectedValue的依赖项属性。当用户输入文本时,该值将被另一个名为ItemsSource的DP验证,以查看它是否在那里。如果没有,我会抛出一个错误。一切正常 - 当出现错误时,UC中的TB有默认的红框。
但我希望用户能够在创建UC实例时在XAML中指定ControlTemplate。所以我想我可以创建另一个类型为ControlTemplate的DP,它们可以绑定到。这似乎有效,但我如何在XAML中实际实现呢?如果它做了类似的事情:
Validation.ErrorTemplate="{Binding ValidationTemplate}"
它抛出一个错误,说“'ErrorTemplate'属性不能被数据绑定。”以下是代码的相关部分:
<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>
和DP本身:
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()));
感谢您的帮助。
欧尼
更新
谢谢你们。我实际上尝试了Adi和Nit的回应。两者都有效,但Adi更接近我想要的,而无需定义用户控件的本地模板。即使我实际上没有创建模板并只添加绑定但设计师给出错误,Nit实际上也会运行。我确实需要调整你的代码Adi以在TextBox本身上设置它:
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);
}
}
谢谢!
答案 0 :(得分:3)
查看Validation.ErrorTemplate
MSDN page,您可以看到它将IsNotDataBindable
元数据属性设置为true
,因此很遗憾,您无法将数据绑定到该属性。
我相信你仍然可以处理你的依赖属性的OnChanged事件,用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);
}
答案 1 :(得分:1)
据我所知,你不能用Binding做你想做的事。 ErrorTemplate可以与StaticResource一起使用。
答案 2 :(得分:1)
由于ErrorTemplate是不可绑定的,您可以做的是使用Resource设置Validation.ErrorTemplate,并在DependancyPropertyChange中用更新的值替换Resource key。
<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="{DynamicResource MyErrorTemplate}"
>
并且依赖属性更改:
public static readonly DependencyProperty ValidationTemplateProperty =
DependencyProperty.Register("ValidationTemplate"
, typeof(ControlTemplate)
, typeof(AutoCompleteComboBox)
, new FrameworkPropertyMetadata(new ControlTemplate(),ValidationTemplateChanged));
private static void ValidationTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
AutoCompleteComboBox control = d as AutoCompleteComboBox;
control.Resources["MyErrorTemplate"] = e.NewValue;
}
答案 3 :(得分:0)
您可以定义并绑定为静态资源:
示例:
<Window.Resources>
<ControlTemplate x:Key="errorTemplate">
<Border BorderBrush="Red" BorderThickness="2">
<Grid>
<AdornedElementPlaceholder x:Name="_el" />
<TextBlock Text="{Binding [0].ErrorContent}"
Foreground="Red" HorizontalAlignment="Right"
VerticalAlignment="Center" Margin="0,0,6,0"/>
</Grid>
</Border>
</ControlTemplate>
</Window.Resources>
元素:
<TextBox Grid.Column="1" Margin="6" Validation.ErrorTemplate="{StaticResource errorTemplate}">
<TextBox.Text>
<Binding Path="Name" ValidatesOnDataErrors="True" UpdateSourceTrigger="PropertyChanged" >
<Binding.ValidationRules>
<local:MinCharsRule MinimumChars="3" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
注意:我从WPF CookBook 4.5中获取了这个例子,它运行良好。