如何在公共文本块中显示所有验证错误消息

时间:2015-04-20 07:46:12

标签: c# wpf validation xaml

我是WPF新手,我正在尝试验证我一直关注此链接的一些WPF控件WPF Binding Validations

我已经理解他们是如何做到的。但我想要的是有一个公共文本块显示所有控件的错误消息,在上面的链接中,他们使用单独的文本块为每个控件查看错误消息,但我想只是更改控件的边框颜色如果出现错误,则显示为红色,并在创建的文本块中显示错误消息,以查看具有错误输入的任何文本框的错误消息。 例如,我有一个文本块

<TextBlock Name="txtError" Foreground="Red" Grid.ColumnSpan="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>

因此,每当任何文本框的文本发生更改且验证规则返回false时,我希望该文本框的边框为红色,并且该消息将显示在上述文本块中。

4 个答案:

答案 0 :(得分:2)

欢迎使用绑定世界,您可以通过仅使用绑定创建一些文本框(如前面的答案中所述)来解决此问题,并使用样式将问题文本框显示为红色。

但是我建议你在wpf中理解DataValidation和DataErrorInfo的概念,在快速搜索中我认为This是一个很好的起点,请阅读它值得花时间。

了解数据错误信息后,您可以在文本框中设置数据错误模板以解决红色边框要求。

答案 1 :(得分:1)

如果在数据模型类中实现IDataErrorInfo InterfaceINotifyDataErrorInfo Interface,则会容易得多。第一个接口提供string Error属性,第二个接口提供返回错误集合的GetErrors方法。然后,您可以将这些属性数据绑定到TextBlockItemsControl,以显示与对象相关的所有错误。

不想复制许多在线示例,我更倾向于指导您。您可以在线How to: Implement Validation Logic on Custom ObjectsHow to implement INotifyDataErrorInfo in WPF 4.5?帖子中找到有关实施这些界面的帮助。

请注意,尽管IDataErrorInfo接口旨在处理单个错误,但如果添加Errors集合属性,则可以更改它以处理多个错误。举个例子:

public string Error
{
    get
    {
        StringBuilder errors = new StringBuilder();
        foreach (string error in Errors) errors.AppendUniqueOnNewLineIfNotEmpty(error);
        return errors.ToString();
    }
}

public override ObservableCollection<string> Errors
{
    get
    {
        errors = new ObservableCollection<string>();
        errors.AddUniqueIfNotEmpty(this["Property1"]);
        errors.AddUniqueIfNotEmpty(this["Property2"]);
        errors.AddUniqueIfNotEmpty(this["PropertyN"]);
        errors.AddRange(ExternalErrors);
        return errors;
    }
}

AddUniqueIfNotEmpty方法只是我创建的一个扩展帮助方法,它可以完成它在锡上所说的内容。

答案 2 :(得分:0)

如果您正在使用MVVM - 只需创建公共属性caled errorMessage并将其绑定到此文本框:

private string _emailMessage;
public string emailMessage
{
    get
    {
        return _emailMessage;
    }
    set
    {
        _emailMessage = value;
        OnPropertyChanged(emailMessage);
    }

现在在xaml中将TextBlock.Text绑定到此属性:

<TextBlock Text="{Binding Path="emailMessage"}  .../>

如果您使用代码隐藏而不是MVVM您可以在每次发生错误时设置Textblock.Text。如下所示:

If(somethingBadHappened)
{
    txtError.Text = "Some error text";
}

答案 3 :(得分:0)

您好搜索引擎的访问者。您可能会对此问题的其他答案感到不知所措。有两个正确答案,具体取决于您对“所有错误”的含义:

当前控件内的所有绑定错误

如果您对可能会产生binding validation errors的属性进行多次绑定,则将它们聚集在一起的正确方法是在控件中添加BindingGroup。然后,您可以查询该对象以获取由其知道的绑定所产生的所有错误。我不会详细介绍如何设置。查看Microsoft文档。

数据对象中的所有INotifyDataErrorInfo错误

也许您实际上没有绑定到各个属性,因为(例如)您正在提示中显示错误消息,并且需要列出用户无法继续操作的所有原因。

当传递null / empty字符串时,您可以滥用GetErrors方法来返回所有已知的错误,但这是一个hack。您还可以添加一个返回所有错误的新属性,但这意味着更改数据模型并为更改的错误添加定制处理。

我为您提供了更好的解决方案:DataErrorsControl。这是一个自定义控件,它:

  1. 查询ErrorSource对象的所有属性并展平错误(在CompositeCollection的帮助下),然后将该集合以只读形式显示为CollectionView
  2. 具有IsExpanded属性,该属性确定它是将所有错误显示为列表,还是一次只显示一个错误
  3. 根据INotifyDataErrorInfo接口的要求,支持异步错误生成

Enjoy!

P.S。我还添加了对在错误中来回导航的支持,但是将必需的按钮保留在默认模板之外,以使其更简单。您可以根据需要添加UI或删除命令处理程序。