Quantcast
Viewing all articles
Browse latest Browse all 7205

How to: Use the POCO Mechanism to implement the IDataErrorInfo Interface


This Code Example demonstrates how you use the POCO mechanism to implement the IDataErrorInfo interface.

For more information about POCO, refer to the following topic: DevExpress MVVM Framework. Introduction to POCO ViewModels.

The following article describes how to automatically generate an IDataErrorInfo implementation: DevExpress MVVM Framework. Data validation. Implementing IDataErrorInfo.


Example Comments

Added By: Jimmy Larkin at: 3/18/2014 7:35:05 AM    

Great you guys did that. Two questions though:
1. How to make the form validated only when the user changes anything? Currently all fields are validated immediately after the form is loaded so when the form opens errors are displayed straight away.
2. A button executes a command on my ViewModel. How can I test if the model is valid?

Added By: Jimmy Larkin at: 3/18/2014 7:36:20 AM    

One more question. I found that the button set up as in example below is not disabled despite errors.

Added By: Vladimir M (DevExpress) at: 3/19/2014 5:46:30 AM    

Hi Jimmy,

Those are great questions.

1. Let's consider validation and the visual cues generated by the editors separately. If we prevented validation on startup, the button would be enabled initially, which is probably not what we want, given that the data is clearly invalid at this point. Just preventing errors from being displayed seems to be a valid solution. Our editors have the ShowError property for this. So, for starters we disable visual cues at startup as follows:

<dxe:TextEdit ... ShowError="False"/>

Now we need to enable the property at an appropriate time. I think it makes sense enabling it when the control loses focus. So, we want to update ShowError when the UIElement.LostKeyboardFocus event is fired.

To achieve this, I will use attached behavior:

public class DelayedValidationResponseBehavior : Behavior<BaseEdit> {
    protected override void OnAttached() {
        base.OnAttached();
        AssociatedObject.LostKeyboardFocus += AssociatedObject_LostKeyboardFocus;
    }
    protected override void OnDetaching() {
        AssociatedObject.LostKeyboardFocus -= AssociatedObject_LostKeyboardFocus;
    }
    void AssociatedObject_LostKeyboardFocus(object sender, RoutedEventArgs e) {
        if(!AssociatedObject.IsFocused)
            AssociatedObject.ShowError = true;
    }
}

The behavior is used as follows:

<dxe:TextEdit NullText="First"
              Text="{Binding FirstName,
                    ValidatesOnDataErrors=True,
                    UpdateSourceTrigger=PropertyChanged}"
              ShowError="False">
    <dxmvvm:Interaction.Behaviors>
        <local:DelayedValidationResponseBehavior/>
    </dxmvvm:Interaction.Behaviors>
</dxe:TextEdit>

Now errors will only show up after the control has lost focus at least once.

2. I will use a service to get the ValidationService.GetHasValidationError value in the ViewModel.

The service:

public interface IValidationErrorsService {
    bool HasErrors { get; }
}
public class ValidationErrorsService : ServiceBase, IValidationErrorsService {
    public bool HasErrors {
        get {
            if(AssociatedObject == null)
                return false;
            return ValidationService.GetHasValidationError(AssociatedObject);
        }
    }
}

The View:

<dxlayout:LayoutControl dxe:ValidationService.IsValidationContainer="True">
        <dxmvvm:Interaction.Behaviors>
            <local:ValidationErrorsService x:Name="ValidationErrorsService"/>
        </dxmvvm:Interaction.Behaviors>
        ...
</dxlayout:LayoutControl>

The ViewModel:

public class SignupViewModel : ViewModelBase {
    public virtual IValidationErrorsService ValidationErrorsService { get { return null; } }
    bool HasValidationErrors { get { return ValidationErrorsService.HasErrors; } }
    ...
}

The ValidationErrorsService property will be overridden by the POCO mechanism to return our service's instance from the View.

Would you please elaborate on the enabled button? Can this behavior be reproduced in our sample? If not, then would you post an application that illustrates the problem?


Viewing all articles
Browse latest Browse all 7205

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>