Using IDataErrorInfo in M-V-VM
Asked Answered
V

4

12

If my domain objects implement IDataErrorInfo, and I am using M-V-VM, how do I propagate errors through the ViewModel into the View? If i was binding directly to the model, I would set the "ValidateOnExceptons" and "ValidateOnErrors" properties to true on my binding. But my ViewModel doesn't implement IDataErrorInfo. Only my model. What do I do?

Clarification I am dealing with an existing codebase that implements IDataErrorInfo in the domain objects. I can't just implement IDataErrorInfo in the my view model.

Voletta answered 4/12, 2008 at 19:42 Comment(0)
G
18

You can implement IDataErrorInfo additionally in your VM and route the calls to the VM to your corresponding domain objects. I think this is the only way without exposing domain objects directly to the view.

Gutta answered 8/12, 2008 at 15:17 Comment(3)
What are you using to route the calls to the VM implementation from the bound entity?Derwood
I don't implemented it, but I think you have to do it manuallyGutta
Hmm doesn't sound workable, I'm looking for a way to tell WPF to look for IDataErrorInfo on the view model.Derwood
B
7

if you are using M-V-VM, the ViewModel should define the IDataErrorInfo interface, not the model.

You could say that the IDataErrorInfo interface is just for the view and it doesn't belong in the model, but that's a question of style.

Having the ViewModel implement the IDataErrorInfo interface and propagate the errors from the model would be the simplest answer.

Battaglia answered 4/12, 2008 at 19:55 Comment(4)
Same question as above, how do you propagate the errors from the entity to the veiwmodel? Have you managed to do this?Derwood
This answer contradicts best practices from MS (msdn.microsoft.com/en-us/library/gg405484(v=PandP.40).aspx): Typically, the model implements the facilities that make it easy to bind to the view. This usually means it supports property and collection changed notification through the INotifyPropertyChanged and INotifyCollectionChanged interfaces. The model may also support data validation and error reporting through the IDataErrorInfo (or INotifyDataErrorInfo) interfaces. These interfaces allow WPF and Silverlight data binding to be notified when values change so that the UI can be updateReservist
@Reservist I'm not sure I agree with that. The model shouldn't be polluted with UI concerns. Implementing a couple of interfaces in the model just to make the UI happy doesn't feel right, that's what the ViewModel is for. Then again, it all depends on the complexity of the model, the size and type of the project, etc. I don't think there's a true answer. But I would try to keep the model clean of any concerns outside business logic.Battaglia
@Battaglia That's sort of how I feel, but I was just pointing out what the Microsoft answer seems to be (albeit not a well-justified answer).Reservist
M
3

There is a good MSDN Magazine article on this topic, WPF Apps With The Model-View-ViewModel Design Pattern: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

According to this article, in The Data Model and Repository section (http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090102) you will find a simple implementation. The Customer is the entity class and the ViewModel gets the error indicators from the entity.

You can use ValidationsRule to check data validity:

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

This is an example of validator styling:

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


Made answered 19/10, 2009 at 22:7 Comment(0)
V
0

The BookLibrary sample application of the WPF Application Framework (WAF) might be interesting for you. It implements the IDataErrorInfo interface as well on the domain objects and it uses the M-V-VM pattern.

Valverde answered 5/7, 2010 at 20:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.