Validation - Make Controls Go Red

MelbourneDeveloperMelbourneDeveloper ✭✭✭AUMember ✭✭✭
edited June 2017 in Xamarin.Forms

When a mandatory property has not filled in, the control should go red as per every application/website on the planet. How do we do this in Xamarin Forms?

In Silverlight/WPF and probably UWP, the INotifyDataErrorInfo interface can be implemented so that controls can be notified when errors occur, and then through binding the UI reflects that an error has occurred which relates to the property that the control is bound to. Does this functionality exist in Xamarin Forms? Will it ever exist?

Note: it's not enough to simply supply some validation metadata like adding an attribute to a property that means that the property is mandatory. Each of our customers has customized business logic and fields may only become mandatory in certain situations. For example, there will be cases where field X is only mandatory when fields Y and Z are also filled in.

Answers

  • JohnHardmanJohnHardman mod GBUniversity mod

    @MelbourneDeveloper - There is more than one way to do this. The usual one is to use Behaviors. See https://blog.xamarin.com/behaviors-in-xamarin-forms/ for an overview

  • MelbourneDeveloperMelbourneDeveloper ✭✭✭ AUMember ✭✭✭

    @JohnHardman , @VenkataSwamyBalaraju

    I understand Behaviours. I guess reading between the lines here, what you are saying is that there's no standard way to do this, and we're going to have to make it up for ourselves. Am I right?

  • NMackayNMackay mod GBInsider, University mod

    @MelbourneDeveloper

    Pretty much, like WPF there is little out of the box apart the mechanisms to roll your own validation with behaviors, forms is very early in the lifecycle.

    Some third party control providers give you some of the features
    http://www.telerik.com/xamarin-ui/dataform (I don't work for progress but we use their controls)

  • MelbourneDeveloperMelbourneDeveloper ✭✭✭ AUMember ✭✭✭
    edited June 2017

    @NMackay , I think you've touched on something here that is in regards to a subtle difference between validation and just making a field go red. You're saying that in "WPF there is little out of the box", but in Silverlight, it is mostly done for you. I'm pretty sure that WPF is the same. In Silverlight, if you implement the INotifyDataErrorInfo interface on the DataContext object, the control automatically glows red with an error message when you raise the ErrorsChanged event and the field is in error. I guess this is really what I'm talking about. Controls in Xamarin Forms should deal with this interface, but it seems that they don't

    Are there any plans for the controls to do this?

    I'm starting to think that maybe this should be a request for the Xamarin Forms team...

  • MelbourneDeveloperMelbourneDeveloper ✭✭✭ AUMember ✭✭✭
    edited June 2017

    Another point I should make here...

    Whenever people bring up validation, the first reaction is to point out bolt on XAML level behaviours etc. which prohibit or encourage behaviour at the UI level. Like for example, you can create a behaviour which would use RegEx to validate an entry for an email address.

    The reality though, is that this is far from adequate in a real life situation. On a basic web form, you may only want to validate things like email address, telephone number and so on, but in our scenario, there is very complex business logic that is handled on the server side. For example, there may be a scenario where the user must enter a "Length" value, but only if the record being edited is a pipe. If the record being edited is a manhole, then "Depth" may be a mandatory field, but not "Length". In another case, perhaps only certain kinds of manholes where the material type is "Steel" would require a "Depth". This kind of logic is nearly impossible to implement at the XAML level, and it is not desirable to apply it at the XAML level because the back end services need to validate this as well. If we do basic validation at the UI level, it's only going to be a duplication of the back end business logic.

    This is why the INotifyDataErrorInfo pattern is so much better. In Silverlight, the server side applies errors to the model object and passes it back to Silverlight. Silverlight automatically knows that there are errors and displays them. We don't have to do anything at the UI level. I'm not sure if UWP has the same functionality or not.

  • NMackayNMackay mod GBInsider, University mod

    @MelbourneDeveloper

    Silverlight is deader than disco. You can't tightly couple validation to the service layer.

  • ChaseFlorellChaseFlorell mod CAInsider, University mod

    I wrote a custom entry that has a bindable ErrorText property.
    https://github.com/XamFormsExtended/Xfx.Controls

    You can see a validation option in the examples

    Disclaimer: I use FluentValidation to handle my validation logic, and then I validate each entry as I type.

    private MyViewModelValidator _validator
    public MyViewModel (MyViewModelValidator validator)
    {
        _validator = validator;
    }
    
    private string _myEntry;
    public string MyEntry
    {
        get { return _myEntry;}
        set { if(SetProperty(ref _myEntry, value)) ValidateMyString(); }
    }
    
    private string _myEntryErrorMessage;
    public string MyEntryErrorMessage
    {
        get { return _myEntryErrorMessage; }
        set { SetProperty(ref _myEntryErrorMessage, value); }
    }
    
    private bool _isValid;
    public bool IsValid
    {
        get { return _isValid; }
        set { SetProperty(ref _isValid, value); }
    }
    
    private void ValidateMyString()
    {
        var result = _validator.Validate(this);
        // check for validator errors ONLY for MyString
    
        // if invalid
        MyEntryErrorMessage = result.// get validation message from validator
        //
    
        IsValid = result.IsValid;
    }
    
  • MelbourneDeveloperMelbourneDeveloper ✭✭✭ AUMember ✭✭✭

    @NMackay said:
    @MelbourneDeveloper

    You can't tightly couple validation to the service layer.

    I'm sure your services have validation right? Or, do you leave your services wide open with no validation?

  • NMackayNMackay mod GBInsider, University mod

    @MelbourneDeveloper said:

    @NMackay said:
    @MelbourneDeveloper

    You can't tightly couple validation to the service layer.

    I'm sure your services have validation right? Or, do you leave your services wide open with no validation?

    No, we don't. I'm just pointing out that mobile patterns don't tightly couple the service layer to the client.

  • MelbourneDeveloperMelbourneDeveloper ✭✭✭ AUMember ✭✭✭
    edited June 2017

    @NMackay said:

    @MelbourneDeveloper said:

    @NMackay said:
    @MelbourneDeveloper

    You can't tightly couple validation to the service layer.

    I'm sure your services have validation right? Or, do you leave your services wide open with no validation?

    No, we don't. I'm just pointing out that mobile patterns don't tightly couple the service layer to the client.

    The service layer will always include validation, so why duplicate validation from the service layer in to the user interface?

    The INotifyDataErrorInfo on WPF and Silverlight is designed to resolve this issue. Unfortunately, it doesn't seem to have an implementation in UWP, or Xamarin Forms. It is a platform agnostic interface which allows for validation at the service layer level to be reflected at the UI level without the need for superfluous XAML behaviours when the data has already been validated at the service layer.

  • MelbourneDeveloperMelbourneDeveloper ✭✭✭ AUMember ✭✭✭

    Here is a working sample of a behavior for the Entry control in Xamarin Forms based on the INotifyDataErrorInfo pattern.

    You can see a full example in this repo:
    https://[email protected]/ChristianFindlay/xamarin-forms-scratch.git

    Just run the app (tested on UWP) and click on the "Validation" button. If you enter anything other than "Test", the control will go red.

    public static class EntryValidationBehaviour
    {
        public static readonly BindableProperty AttachBehaviorProperty =
            BindableProperty.CreateAttached(
                "AttachBehavior",
                typeof(bool),
                typeof(EntryValidationBehaviour),
                false,
                propertyChanged: OnAttachBehaviorChanged);
    
        public static bool GetAttachBehavior(BindableObject view)
        {
            return (bool)view.GetValue(AttachBehaviorProperty);
        }
    
        public static void SetAttachBehavior(BindableObject view, bool value)
        {
            view.SetValue(AttachBehaviorProperty, value);
        }
    
        static void OnAttachBehaviorChanged(BindableObject view, object oldValue, object newValue)
        {
            var entry = view as Entry;
            if (entry == null)
            {
                return;
            }
    
            bool attachBehavior = (bool)newValue;
            if (attachBehavior)
            {
                entry.TextChanged += OnEntryTextChanged;
            }
            else
            {
                entry.TextChanged -= OnEntryTextChanged;
            }
        }
    
        static void OnEntryTextChanged(object sender, TextChangedEventArgs args)
        {
            var entry = sender as Entry;
            if (entry == null)
            {
                return;
            }
    
            var notifyDataErrorInfo = entry.BindingContext as INotifyDataErrorInfo;
            if(notifyDataErrorInfo==null)
            {
                return;
            }
    
            entry.BackgroundColor = notifyDataErrorInfo.HasErrors ? Color.Red : Color.Default;
        }
    }
    
  • MelbourneDeveloperMelbourneDeveloper ✭✭✭ AUMember ✭✭✭
    edited June 2017

    So, the above proves that this type of functionality CAN be done in Xamarin Forms. The issue is that it doesn't exist out of the box. I guess that in a sense, I can understand why Microsoft/Xamarin have decided not to apply this functionality across the board in UWP/Xamarin Forms. In Silverlight and WPF, this functionality comes out of the box. This is a good thing in the sense that it allows you to focus on the important stuff: building the app without worrying about how errors are displayed on screen. However, the styling is tightly embedded in the platform. To override the styling is complex.

    So, I guess what I'm asking here is, is there a project floating around on the web with a bunch of behaviours that implement this kind of functionality for Xamarin Forms controls?

    Meantime, I will start adding behaviours to an existing project I have, but long term, I would hope that some of this work is done for us...

  • MelbourneDeveloperMelbourneDeveloper ✭✭✭ AUMember ✭✭✭

    I've added two behaviours to this repo which is a collection of Xamarin Forms UI components that don't come out of the box. The code will be maintained in this repo going to in to future. The behaviours are EditorValidationBehaviour, and EntryValidationBehaviour. They are only rudimentary and functionality will be added over time.
    https://github.com/MelbourneDeveloper/Adapt.Presentation.git

  • MelbourneDeveloperMelbourneDeveloper ✭✭✭ AUMember ✭✭✭

    Here's another article where someone else has done essentially the same thing here (albeit in a much more complicated way):
    http://www.davidezordan.net/blog/?p=8093

Sign In or Register to comment.