Question

I am trying to apply some validation to a rather complex set of technologies for our existing product while implementing a new architecture. Most of this is going well, however I still need to use WinForms for the existing product and therefore need to use the ErrorProvider class for showing validation errors. (The new product will be able to use the new architecture via WPF/MVC too, but I don't have the time or resources for a complete rewrite from scratch to eliminate the WinForms at the moment, hence the mix of technologies)

The basic layout of the new architecture is as follows:

Database -> Model (via NHibernate) -> ViewModel -> Form (using BindingSource)

So my question is, how can I utilise a ValidationResult from a failed DataAnnotation check on a Model's property on a ErrorProvider on the Form?

I have managed to get the list of ValidationResults up to the Form, but setting them to a specific control is alluding me without writing code for each Control, I would prefer to create a generic way of doing this via the BindingSource, possibly in a base Form.

I know I could do this a lot easier if the DataAnnotations were on the ViewModels, but if I did that then I would have to keep all of them up to date if a change was made to the Model/Database table, and that would require plenty of repeated code.

I understand that this question is a bit vague, but considering the fact this spans the majority of the architecture, I can't see a better way of explaining it without writing reams of mostly irrelevant code. If you want extra information, then please ask and I will provide it.

Thanks very much.

Was it helpful?

Solution

not sure if this will help, but see if changing your btn_Save to be like this and then add the GetControlBoundToMember method as well, I am guessing your btnSave method looks similar to the one below. You will also need to add an ErrorProvider Control to your form and call it err1 and move any controls that might be in a groupbox out of the groupbo and place them onto the form, unless you create a recursive method that search through controls that have a collect of controls.

     private void btnSave_Click(object sender, EventArgs e)
    {
        if (_entity != null)
        {
            try
            {
                _service.Save(_entity.UpdateEntity());
            }
            catch (InvalidOperationException ex)
            {
                //do something here to display errors
                listBox1.Items.Clear();
                foreach (var r in _entity.Errors)
                {
                    listBox1.Items.Add(r.ErrorMessage);

                    foreach (var c in GetControlBoundToMember(r.MemberNames.ToList()))
                    {
                        err1.SetError(c, r.ErrorMessage);
                    }
                }
            }
        }
    }


    private IList<Control> GetControlBoundToMember(IList<string> memberNames)
    {

        List<Control> controls = new List<Control>();

        foreach (Control control in this.Controls)
        {
            foreach (var mn in memberNames)
            {
                foreach (Binding binding in control.DataBindings)
                {
                    if (binding.BindingMemberInfo.BindingField == mn) controls.Add(control);
                }
            }
        }

        return controls;
    }

AB

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top