c# - MVVM 模式、IDataErrorInfo 和绑定(bind)显示错误?

标签 c# .net wpf mvvm binding

关于 MSDN Magazine它有一篇关于 MVVM 的好文章,他们将 Xaml 中的验证错误绑定(bind)到 Validation.ErrorTemplate="{x:Null}"。我不明白为什么以及如何从 IDataErrorInfo 中显示错误?谁能告诉我如何使用 MVVM 方法将错误消息显示在屏幕上?

最佳答案

绑定(bind)到支持 IDataErrorInfo 的对象时,需要考虑 WPF 绑定(bind)类的几个功能:

  1. ValidatesOnDataErrors 必须为真。这指示 WPF 在基础对象上查找和使用 IDataError 接口(interface)。

  2. 如果源对象的 IDataError 接口(interface)报告验证问题,附加属性 Validation.HasError 将在目标对象上设置为 true。然后,您可以将此属性与触发器一起使用,以更改控件的工具提示以显示验证错误消息(我在当前项目中这样做,最终用户很喜欢)。

  3. Validation.Errors 附加属性将包含上次验证尝试导致的任何 ValidationResult 错误的枚举。如果您要使用工具提示方法,请使用 IValueConverter 仅检索第一个项目...否则您会遇到显示错误消息本身的绑定(bind)错误。

  4. 绑定(bind)类公开 NotifyOnValidationError,当它为 True 时,每当验证规则的状态发生变化时,都会导致路由事件从绑定(bind)控件冒泡。如果您想在绑定(bind)控件的容器中实现事件处理程序,然后向列表框添加验证消息或从列表框删除验证消息,这将非常有用。

MSDN 上有用于执行两种反馈方式(工具提示和列表框)的示例,但我将粘贴到我负责在我的 DataGridCells 和 TextBox 上实现工具提示反馈的代码下方...

DataGridCell 样式:

   <Style TargetType="{x:Type dg:DataGridCell}"
           x:Key="DataGridCellStyle">

      <Setter Property="ToolTip"
              Value="{Binding Path=Column.(ToolTipService.ToolTip),RelativeSource={RelativeSource Self}}" />

      <Style.Triggers>
        <Trigger Property="Validation.HasError"
                 Value="True">
          <Setter Property="ToolTip"
                  Value="{Binding RelativeSource={RelativeSource Self},Path=(Validation.Errors), Converter={StaticResource ErrorContentConverter}}" />
        </Trigger>
      </Style.Triggers>

    </Style>

文本框样式:

     <Style x:Key="ValidatableTextBoxStyle" TargetType="TextBox">
  <!--When the control is not in error, set the tooltip to match the AutomationProperties.HelpText attached property-->
  <Setter Property="ToolTip"
          Value="{Binding RelativeSource={RelativeSource Mode=Self},Path=(AutomationProperties.HelpText)}" />

          <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="true">
              <Setter Property="ToolTip"
                      Value="{Binding RelativeSource={x:Static RelativeSource.Self},Path=(Validation.Errors)[0].ErrorContent}" />
            </Trigger>
          </Style.Triggers>
        </Style>

ErrorContentConverter(用于检索工具提示的第一条验证错误消息):

Imports System.Collections.ObjectModel

Namespace Converters

    <ValueConversion(GetType(ReadOnlyObservableCollection(Of ValidationError)), GetType(String))> _
    Public Class ErrorContentConverter
        Implements IValueConverter

        Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
            Dim errors As ReadOnlyObservableCollection(Of ValidationError) = TryCast(value, ReadOnlyObservableCollection(Of ValidationError))
            If errors IsNot Nothing Then
                If errors.Count > 0 Then
                    Return errors(0).ErrorContent
                End If
            End If
            Return String.Empty
        End Function

        Public Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
            Throw New NotImplementedException()
        End Function

    End Class

End Namespace

...最后是在文本框中使用样式的示例:

    <TextBox Text="{Binding Path=EstimatedUnits,ValidatesOnDataErrors=True,NotifyOnValidationError=True}"
             Style="{StaticResource ValidatableTextBoxStyle}"
             AutomationProperties.HelpText="The number of units which are likely to sell in 1 year." />

关于c# - MVVM 模式、IDataErrorInfo 和绑定(bind)显示错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1123062/

相关文章:

c# - 如何通过 API 从维基百科获取地标性地点的标题?

c# - 比较并组合字符串以获得重复项

.net - 明确的控制措施不会将其处置-有什么风险?

wpf - 在设计时包 uri 有效,但在运行时无效?

c# - 忽略 WPF 应用程序中的 Alt+F4

c# - 将值属性添加到 ASP.NET 复选框

c# - 内存泄漏将 imagebrush 加载到 grid.background

c# - 在 List<[linq_custom_object]>() 上实现 .Distinct() 的正确方法是什么?

.net - 序列化 .Net SqlTransaction?

wpf - IsMouseOver 鼠标捕获时