C# UserControl中的Binding Validation.ErrorTemplate
我有一个用户控件,它有一个文本框,其中它的文本属性绑定到一个名为SelectedValue的依赖属性。当用户输入文本时,将根据另一个名为ItemsSource的DP验证该值,以查看它是否在其中。如果不是,我抛出一个错误。一切正常-当出现错误时,UC中的TB周围有默认的红色框 但我希望用户在创建UC实例时能够在XAML中指定ControlTemplate。所以我想我可以创建另一个类型为ControlTemplate的DP,它们可以绑定到。这似乎是可行的,但我如何在XAML中真正实现它呢?如果它执行以下操作:C# UserControl中的Binding Validation.ErrorTemplate,c#,wpf,validation,xaml,dependency-properties,C#,Wpf,Validation,Xaml,Dependency Properties,我有一个用户控件,它有一个文本框,其中它的文本属性绑定到一个名为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>
谢谢你的帮助
厄尼
更新: 谢谢各位。事实上,我试过阿迪和尼特的回答。这两种方法都有效,但Adi更接近于我所寻找的,不必定义用户控件本地的模板。即使我没有实际创建模板,只是添加了绑定,但设计器给出了一个错误,Nit也会运行。我确实需要对您的代码进行一些Adi调整,以便将其设置在文本框本身上:
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);
}
}
谢谢 查看,您可以看到它的元数据属性设置为true
,因此不幸的是,您无法将数据绑定到该属性
我相信您仍然可以处理依赖项属性的OnChanged事件,自己使用验证来设置该属性。SetErrorTemplate()
:
据我所知,你不能用装订来做你想做的事。ErrorTemplate可与StaticResource一起使用。由于ErrorTemplate是不可绑定的,您可以使用资源设置Validation.ErrorTemplate,并在DependencyPropertyChange中使用更新的值替换资源键
<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}"
>
您可以定义并绑定为静态资源: 例如:
<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第232页中获取了这个示例,它非常有效
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;
}
<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>