【问题标题】:Show Validation Error Template on Controls within a UserControl in WPF在 WPF 中的 UserControl 内的控件上显示验证错误模板
【发布时间】:2013-02-04 14:01:09
【问题描述】:

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

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

UserControl的name字段绑定如下。

<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 解决这个问题?我是否忽略了一些明显的东西?

【问题讨论】:

  • 相关问题here和here
  • 谢谢,LPL。在我研究这个问题的过程中,我已经看到了这两个问题。第二个链接上接受的答案是使用我在问题中引用的转换器。这对我来说似乎很错误。第一个问题中接受的答案似乎对我也不起作用。

标签: c# wpf validation mvvm idataerrorinfo


【解决方案1】:

如果绑定到您的UserControl 使用ValidatesOnDataErrors=True,则将使用UserControl 的ErrorTemplate。但是你可以用Validation.ErrorTemplate Attached Property去掉红色边框。

UserControl 中的所有控件只有在您通过为支持的 DependencyProperties 实现 IDataErrorInfo 来验证它们的绑定时才会显示红色边框。

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 Property。

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

【讨论】:

  • 再次感谢 LPL。我最初尝试了类似的更改,但我无法确定 UserControl 内部的哪个 TextBox 有错误,因为在 TextBox 本身上调用 Validation.GetHasError 总是返回 false。在我的 UserControl 中有两个文本框,是否可以确定哪个框实际上有错误?
  • 不确定我之前做错了什么,但这似乎对我有用。我仍然看不到如何区分唯一文本框上的错误,但此时我只会对其中一个进行验证。谢谢,LPL!
  • 我添加了一个建议来区分错误。 ;)
猜你喜欢
  • 2010-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-04
  • 2021-08-26
  • 1970-01-01
  • 2016-12-03
相关资源
最近更新 更多