在WPF中的UserControl中显示控件的验证错误模板

本文关键字:验证 错误 控件 显示 WPF 中的 UserControl | 更新日期: 2023-09-27 18:00:05

如何使WPF错误模板出现在WPF中UserControl中的控件上?

我有一个UserControl,它包含两个标签、两个文本框和一个复选框。其中一个TextBoxes表示实体的名称,它绑定到ViewModel公开的Model属性之外的name属性,该属性是我的Window的DataContext。Model类实现了IDataErrorInfo接口,我已经通过单元测试确认,当Name为空时,会通过属性索引器实现返回错误。我已经绑定到UserControl中支持Name TextBox的依赖项属性,当遇到验证错误时,WPF错误模板会在整个UserControl周围放置红色边框,而不仅仅是Name TextBox。

与UserControl的名称字段的绑定如下。

<vc:MyUserControl ItemName="{Binding Model.Name, ValidatesOnDataErrors=True}" />

我的UserControl和支持的DependencyProperty的类似版本如下。

<UserControl>
    <Grid>
       <TextBox Text="{Binding ItemName}" />
    </Grid>
</UserControl>
public partial class MyUserControl: UserControl
{
    public static readonly DependencyProperty ItemNameProperty = 
        DependencyProperty.Register(
            "ItemName", 
            typeof(string), 
            typeof(MyUserControl), 
            new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)
    );
    public string ItemName
    {
        get { return (string)GetValue(ItemNameProperty); }
        set { SetValue(ItemNameProperty, value); }
    }
}

到目前为止,我发现的与此问题有关的信息都是关于Silverlight或使用转换器不显示红色边框(这对我来说没有意义)。这些信息都是在stackoverflow上找到的。

有人能用WPF解决这个问题吗?我是不是忽略了一些显而易见的东西?

在WPF中的UserControl中显示控件的验证错误模板

如果到UserControl的绑定使用ValidatesOnDataErrors=True,则将使用ErrorTemplate作为UserControl。但是您可以使用Validation.ErrorTemplate Attached属性删除红色边框。

如果您通过为支持的DependencyProperty实现IDataErrorInfo来验证它们的绑定,那么UserControl中的所有控件将只显示红色边框。

public class MyUserControl : UserControl, IDataErrorInfo
{
   public static readonly DependencyProperty ItemNameProperty =
       DependencyProperty.Register(
           "ItemName",
           typeof(string),
           typeof(MyUserControl),
           new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)
   );
   public string ItemName
   {
      get { return (string)GetValue(ItemNameProperty); }
      set { SetValue(ItemNameProperty, value); }
   }
   public string Error
   {
      get { throw new NotImplementedException(); }
   }
   public string this[string columnName]
   {
      get
      {
         // use a specific validation or ask for UserControl Validation Error 
         return Validation.GetHasError(this) ? "UserControl has Error" : null;
      }
   }
}

这里是简化的XAML

<UserControl Validation.ErrorTemplate="{x:Null}">
   <Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}">
      <TextBox Text="{Binding ItemName, ValidatesOnDataErrors=True}" />
   </Grid>
</UserControl>

添加

如果要区分错误,可以获取DependencyProperty的BindingExpression并检查HasError属性。

BindingExpression be = BindingOperations.GetBindingExpression(this, ItemNameProperty);
return be != null && be.HasError ? "ItemName has Error" : null;