【问题标题】:Using IDataErrorInfo in M-V-VM在 M-V-VM 中使用 IDataErrorInfo
【发布时间】:2010-09-25 09:39:07
【问题描述】:

如果我的域对象实现了 IDataErrorInfo,并且我正在使用 M-V-VM,我如何通过 ViewModel 将错误传播到 View 中?如果我直接绑定到模型,我会在绑定上将“ValidateOnExceptons”和“ValidateOnErrors”属性设置为 true。但是我的 ViewModel 没有实现 IDataErrorInfo。只有我的模型。我该怎么办?

澄清 我正在处理在域对象中实现 IDataErrorInfo 的现有代码库。我不能只在我的视图模型中实现 IDataErrorInfo。

【问题讨论】:

    标签: wpf validation mvvm idataerrorinfo


    【解决方案1】:

    如果您使用的是 M-V-VM,ViewModel 应该定义 IDataErrorInfo 接口,而不是模型。

    您可以说 IDataErrorInfo 接口仅用于视图,不属于模型,但这是样式问题。

    让 ViewModel 实现 IDataErrorInfo 接口并从模型传播错误将是最简单的答案。

    【讨论】:

    • 与上述相同的问题,如何将错误从实体传播到 veiwmodel?你做到了吗?
    • 这个答案与 MS (msdn.microsoft.com/en-us/library/gg405484(v=PandP.40).aspx) 的最佳实践相矛盾:通常,模型实现了可以轻松绑定到视图的工具。这通常意味着它通过 INotifyPropertyChanged 和 INotifyCollectionChanged 接口支持属性和集合更改通知。该模型还可以通过 IDataErrorInfo(或 INotifyDataErrorInfo)接口支持数据验证和错误报告。这些接口允许在值更改时通知 WPF 和 Silverlight 数据绑定,以便更新 UI
    • @Pat 我不确定我是否同意。该模型不应受到 UI 问题的污染。在模型中实现几个接口只是为了让 UI 快乐感觉不对,这就是 ViewModel 的用途。话又说回来,这一切都取决于模型的复杂性、项目的规模和类型等。我认为没有真正的答案。但我会尽量让模型不考虑业务逻辑之外的任何问题。
    • @gcores 这就是我的感觉,但我只是指出微软的答案似乎是什么(尽管不是一个合理的答案)。
    【解决方案2】:

    您可以在 VM 中另外实现 IDataErrorInfo,并将对 VM 的调用路由到相应的域对象。我认为这是不将域对象直接暴露给视图的唯一方法。

    【讨论】:

    • 您使用什么将调用从绑定实体路由到 VM 实现?
    • 我没有实现,但我认为你必须手动完成
    • 嗯听起来不太可行,我正在寻找一种方法来告诉 WPF 在视图模型上查找 IDataErrorInfo。
    【解决方案3】:

    关于这个主题有一篇很好的 MSDN 杂志文章,具有模型-视图-视图模型设计模式的 WPF 应用程序:http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

    根据本文,在数据模型和存储库部分 (http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090102),您将找到一个简单的实现。 Customer 是实体类,ViewModel 从实体获取错误指示符。

    您可以使用 ValidationsRule 来检查数据的有效性:

    <TextBox x:Name="title" VerticalAlignment="Top" TextWrapping="Wrap" Grid.Column="1" MinWidth="20">
      <TextBox.Text>
        <Binding Path="Title" UpdateSourceTrigger="LostFocus">
          <Binding.ValidationRules>
            <Validators:StringRangeValidationRule MinimumLength="1" MaximumLength="30" 
                                                ErrorMessage="Address is required and must be less than 30 letters." />
          </Binding.ValidationRules>
        </Binding>
      </TextBox.Text>
    </TextBox>
    

    这是验证器样式的示例:

    <Application.Resources>
      <Style TargetType="{x:Type TextBox}">
      <Setter Property="Validation.ErrorTemplate">
        <Setter.Value>
          <ControlTemplate>
            <DockPanel LastChildFill="True">
              <Image Source="/Images/error.png" Width="25" Height="25" ToolTip="{Binding ElementName=MyAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}" />
              <TextBlock DockPanel.Dock="Right"
                  Foreground="Orange"
                  Margin="5" 
                  FontSize="12pt"
                  Text="{Binding ElementName=MyAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
              </TextBlock>
    
              <Border BorderBrush="Red" BorderThickness="3">
              <AdornedElementPlaceholder Name="MyAdorner" />
            </Border>
          </DockPanel>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
    <Style.Triggers>
      <Trigger Property="Validation.HasError" Value="true">
        <Setter Property="ToolTip"
            Value="{Binding RelativeSource={RelativeSource Self}, 
            Path=(Validation.Errors)[0].ErrorContent}"/>
      </Trigger>
    </Style.Triggers>
    


    【讨论】:

      【解决方案4】:

      WPF Application Framework (WAF)BookLibrary 示例应用程序可能会让您感兴趣。它在域对象上也实现了 IDataErrorInfo 接口,并使用 M-V-VM 模式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-30
        • 2011-03-02
        • 1970-01-01
        • 2010-10-28
        相关资源
        最近更新 更多