简体   繁体   English

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

[英]Show Validation Error Template on Controls within a UserControl in WPF

How do you get the WPF error template to appear on a control within a UserControl in WPF? 如何让WPF错误模板出现在WPF中UserControl的控件上?

I have a UserControl containing two Labels, two TextBoxes, and a CheckBox. 我有一个UserControl包含两个标签,两个TextBox和一个CheckBox。 One of the TextBoxes represents the name of the entity and it is bound to a Name property off of a Model property exposed by my ViewModel, which is the DataContext of my Window. 其中一个TextBoxes表示实体的名称,它绑定到ViewModel公开的Model属性的Name属性,该属性是我的Window的DataContext。 The Model class implements the IDataErrorInfo interface and I have confirmed through Unit Testing that when the Name is blank an error is returned through the property indexer implementation. Model类实现了IDataErrorInfo接口,我通过单元测试确认,当Name为空时,通过属性索引器实现返回错误。 I have bound to the Dependency Property backing the Name TextBox in my UserControl and when the validation error is encountered the WPF error template places a red border around the entire UserControl rather than just the Name TextBox. 我已经绑定了支持UserControl中的Name TextBox的Dependency Property,当遇到验证错误时,WPF错误模板在整个UserControl周围放置一个红色边框,而不仅仅是Name TextBox。

The binding to the name field of the UserControl is as follows. 绑定到UserControl的名称字段如下。

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

A simiplified version of my UserControl and the backing DependencyProperty is as follows. 我的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); }
    }
}

The information I have found relating to this issue thus far has all been in regards to Silverlight or using a converter to not show the red border (which did not make sense to me). 到目前为止,我发现的与此问题有关的信息都是关于Silverlight或使用转换器不显示红色边框(这对我来说没有意义)。 This information was all found here on stackoverflow. 这些信息都是在stackoverflow上找到的。

Has anyone been able to solve this issue with WPF? 有没有人能用WPF解决这个问题? Am I overlooking something obvious? 我忽略了一些明显的东西吗

The ErrorTemplate for UserControl will be used if bindings to your UserControl use ValidatesOnDataErrors=True . 如果绑定到UserControl使用ValidatesOnDataErrors=True将使用ErrorTemplate for UserControl But you can remove the red border with the Validation.ErrorTemplate Attached Property . 但是您可以使用Validation.ErrorTemplate附加属性删除红色边框。

All controls within your UserControl will only show a red border if you validate their bindings by implementing IDataErrorInfo for the backing DependencyProperties too. 如果您通过为后备DependencyProperties实现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;
      }
   }
}

and here the simplified XAML 这里是简化的XAML

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

Addition 加成

If you want to differentiate between errors you can get the BindingExpression for your DependencyProperty and check the HasError Property . 如果要区分错误,可以获取DependencyProperty的BindingExpression并检查HasError属性

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM