Powered by MSDN

US - English
NEW! Silverlight 5 is available Learn More

How to manually validate an object and have the results... RSS

14 replies

Last post Oct 25, 2010 09:43 AM by jmix90

(0)
  • jemiller

    jemiller

    Member

    445 Points

    237 Posts

    How to manually validate an object and have the results automatically added to a ValidationSummary?

    Jul 17, 2009 08:47 PM | LINK

    Does anyone know if it's possible to manually validate an object and have the results automatically added to a ValidationSummary? I have property-level validation working, but, I need to have it validate the object as a whole when the user clicks the OK button. Note, I am not using DataForm. I want to know how to do it without DataForm. I'm assuming that I would need to make a call like the following in my OK button handler?

    Validator.ValidateObject(DataContext, new ValidationContext(DataContext, null, null));

    The question is, do I have to manually add the results of this to the ValidationSummary? Is there a way to have it done automatically like what happens for property-level validation? I have my property-level checks in the setters of my entity. 

     

  • Sledge70

    Sledge70

    Star

    8044 Points

    1369 Posts

    Re: How to manually validate an object and have the results automatically added to a ValidationSu...

    Jul 21, 2009 12:38 AM | LINK

    The easiest way would be to update the bindingexpression for each property which will force validation to occur. A bit of a hack but saves you having to have your validation rules duplicated from your entity setter.

    This hack will loop through all children of an element and force validation. You could make this more generic but this should give you the idea of how to make it happen. Additionally you could throw in a call to Validation.GetErrors(uiElement) after bindingExpression.UpdateSource which will return any validation errors on the element. Handy if you want to manage your errors centrally with some other control etc.

    Have only tested this in Silverlight 3.

            ForceValidation(LayoutRoot.Children);

            private void ForceValidation(IEnumerable uiElements)
            {
                foreach (var uiElement in uiElements)
                {
                    BindingExpression bindingExpression = null;
                    
                    switch (uiElement.GetType().ToString())
                    {
                        case "System.Windows.Controls.StackPanel":
                        case "System.Windows.Controls.Panel":
                            ForceValidation(((Panel)uiElement).Children);
                            break;
    
                        case "System.Windows.Controls.TextBox":
                            bindingExpression = ((TextBox)uiElement).GetBindingExpression(TextBox.TextProperty);
                            break;
    
                        case "System.Windows.Controls.RadioButton":
                            bindingExpression = ((RadioButton)uiElement).GetBindingExpression(ToggleButton.IsCheckedProperty);
                            break;
                    }
    
                    if (bindingExpression == null || bindingExpression.ParentBinding == null) continue;
                    if (!bindingExpression.ParentBinding.ValidatesOnExceptions) continue;
    
                    bindingExpression.UpdateSource();
                }
            }

     

    Regards,

     

  • sapientcoder

    sapientcoder

    Member

    492 Points

    99 Posts

    Re: How to manually validate an object and have the results automatically added to a ValidationSu...

    Jul 21, 2009 04:20 PM | LINK

    ValidationSummary simply takes whatever control (UIElement) is in "Target" property and hooks up to its BindingValidationError event. If you don't set a target in your XAML or code-behind and you leave it null, then ValidationSummary just calls VisualTreeHelper.GetParent() on itself and hooks into its parent control. Unfortunately, if you want the errors to be automatically added for you, that's the approach you have to use (letting errors bubble up through the BindingValidationError event).

    In your case, if you want to manually use the Validator class to validate your object, you'll need to manually add the resulting error messages to the ValidationSummary. To do that, just add ValidationSummaryItems to the ValidationSummary.Errors collection.

    Bart McDonough | Principal Consultant | Incline Technical Group

    Blog: doseofdotnet.wordpress.com
  • enantiomer2000

    enantiomer2000

    Member

    45 Points

    62 Posts

    Re: How to manually validate an object and have the results automatically added to a ValidationSu...

    Aug 04, 2009 07:20 PM | LINK

     Nice work Sledge.  To add a bit to your code, you can use TreeViewHelper to simplify the iteration process:

     

    private void ForceValidation(UIElement element)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
                {
                    UIElement child = (UIElement)VisualTreeHelper.GetChild(element, i);
                    ForceValidation(child);
                }
    
                BindingExpression bindingExpression = null;
    
                string uiElementType = element.GetType().ToString();
                switch (uiElementType)
                {
                    case "System.Windows.Controls.TextBox":
                        bindingExpression = ((TextBox)element).GetBindingExpression(TextBox.TextProperty);
                        break;
    
                    case "System.Windows.Controls.RadioButton":
                        bindingExpression = ((RadioButton)element).GetBindingExpression(RadioButton.IsCheckedProperty);
                        break;
                }
    
                if (bindingExpression == null || bindingExpression.ParentBinding == null) return;
                if (!bindingExpression.ParentBinding.ValidatesOnExceptions) return;
    
                bindingExpression.UpdateSource();
            }    

      

    Would this cover all scenarios?  Seems to work for me.

  • enantiomer2000

    enantiomer2000

    Member

    45 Points

    62 Posts

    Re: How to manually validate an object and have the results automatically added to a ValidationSu...

    Aug 06, 2009 02:28 AM | LINK

     I may have spoken to soon.  It looks like there are some real issue with using controls like TabControl and doing validation in this method.  Seems as though binding doesn't actually get set until the tab is loaded into view.  You can confirm this by setting a bad binding Path value and watching the output window to see when it gives you the warning, only after it is selected into view. This means that you can't use the above method of forcing validation on your controls.  Is this UI Virtualization?  Is there a way of telling silverlight not to virtualize?  It doesn't make sense for me since I only have about 7 tabs.  Any ideas on this one? 

  • mtiede@swtechnologies.com

    mtiede@swtec...

    Contributor

    4417 Points

    1944 Posts

    Re: How to manually validate an object and have the results automatically added to a ValidationSu...

    Aug 18, 2009 08:27 PM | LINK

     I am bumping into this same issue.  Even though iterating the controls doesn't generate the validation on the "hidden" tabs, if you do a ValidateObject, it WILL raise an exception (which doesn't go in the ValidationSummary).

    Not sure what to do yet.  "Desperately Seeking Solution"  (instead of Susan :-)

  • jemiller

    jemiller

    Member

    445 Points

    237 Posts

    Re: How to manually validate an object and have the results automatically added to a ValidationSu...

    Aug 18, 2009 09:26 PM | LINK

    Am I the only one that gets frustrated with the constant churn of this stuff? While Microsoft seems to have made a lot of progress in Silverlight 3 in terms of making it easier to implement line of business applications, it's still not there yet IMHO. I don't understand why this stuff has to be such a PITA. I also don't understand why having a workable validation framework is such an afterthought. Microsoft has always sucked in this area as far as I'm concerned. And they still don't have it right if there isn't support for a. a way to call methods asynchronously to do validation, or b. a way to make synchronous network calls. There should also be a way of doing validation without having to put attributes on the model classes which may have been generated from a non-Microsoft web service. While writing server side apps is a PITA do to all the hacks and stupid stateless behavior, this is an equal or greater PITA because you have to screw around with issues with serializing everything and sending it over the wire to the client and then still have to implement all the same validation checks on the client and the server. I would like to see Microsoft make some improvements to Web Forms. Specifically, I would like to see WPF-like data binding (i.e. get rid of all the ADO.NET DataSet crap). If I had that, I think I'd rather just stick with doing everything on the server side. I really don't see much benefit to doing it on the client. It's a lot of extra hassle and IMHO still isn't fully baked. I also think ASP.NET MVC is a step backwards if it lacks controls like ListView.

  • mtiede@swtechnologies.com

    mtiede@swtec...

    Contributor

    4417 Points

    1944 Posts

    Re: How to manually validate an object and have the results automatically added to a ValidationSu...

    Aug 18, 2009 09:42 PM | LINK

     Nope.  :-)

    Interestingly the ValidationContext has an IServiceProvider argument that is as yet undocumented.  Could be they are header there...

  • Sledge70

    Sledge70

    Star

    8044 Points

    1369 Posts

    Re: Re: How to manually validate an object and have the results automatically added to a Validati...

    Aug 19, 2009 12:36 AM | LINK

    I have to agree that it all seems like an afterthought.

    I think the main issue we're facing is we all want to subscribe to the view/viewmodel pattern and have everything xaml based yet we're limited by Microsofts interpretation of what we need.

    All the current issues we face can be fixed by code behind without question. I  get the feeling that validation in SL is taking the same course of datacontrols etc that existed in VB years ago. Yes they were usable for a start point but once you got into real world scenarios or should I say LOB apps to be current [:)] you quite quickly hit the wall.

    On the upside I still think SL is at an early enough stage to take critical feedback on-board and change for the better.

  • mtiede@swtechnologies.com

    mtiede@swtec...

    Contributor

    4417 Points

    1944 Posts

    Re: Re: How to manually validate an object and have the results automatically added to a Validati...

    Aug 19, 2009 02:03 AM | LINK

     I was just poking around in Validator using Reflector.  I saw TryValidateObject that gives back a ICollection<ValidationResult>.  Unfortunately, as far as I can figure out, that list is just a list of error messages.  What I really want is what GetValidationErrors gets: a list of IEnumerable<ValidationError>.  Now THAT has the objects in them.  I THINK with that I could get what I want into the ValidationSummary.

    I think I am going to make my own Validator object and get what the actual one gets, but doesn't make public :-(

     ... time passes ...

     hmm..   I don't think it hsa the original source object in it after all.  Oh well...