wpf - Adding an ExceptionValidationRule to a Binding in code -


i have been developing errorprovider control inherits decorator. validates elements within control bound something. loops through every binding , within frameworkelement , adds exceptionvalidationrule dataerrorvalidation binding's validationrules.

this method work:

private sub applyvalidationrulestobindings()     dim bindings dictionary(of frameworkelement, list(of binding)) = getbindings()      each felement in bindings.keys         dim knownbindings list(of binding) = bindings(felement)          each knownbinding binding in knownbindings             'applying exception , data error validation rules'             knownbinding.validationrules.add(new exceptionvalidationrule())             knownbinding.validationrules.add(new dataerrorvalidationrule())         next      next end sub 

apparently dataerrorvalidationrule applied binding, exceptionvalidationrule not.

does know why might case?

edit: ok, little more info on problem.

i've been reading tons of msdn documentation on validation , binding class. binding.updatesourceexceptionfilter property allows specify function handles exceptions occur on binding if exceptionvalidationrule has been associated binding.

i added method updatesourceexceptionfilter property , guess what! executed. but!! though returned exception, validationerror object not added validation.errors collection of bound element though msdn documentation said be...

i commented out code adds exceptionvalidationrule dynamically , manually added 1 binding in xaml so:

<textbox horizontalalignment="left" name="textbox1" verticalalignment="top"                                     width="200">   <textbox.text>     <binding path="name">       <binding.validationrules>         <exceptionvalidationrule />       </binding.validationrules>     </binding>   </textbox.text>  </textbox> 

the updatesourceexception method executed (i didn't change it) , error added validation.errors msdn stated.

what curious whole thing fact exceptionvalidationrule in fact added binding when done through vb.net code (or else the updatesourceexception never have executed); however, validate.errors not updated error.

as stated earlier, dataerrorvalidationrule added binding , works properly...i'm having problems exceptionvalidationrule.

my solution:

it turns out had call bindingoperations.setbinding method binding , property apply validation rules binding. had no way of retrieving dependencyproperty element/binding in applyvalidationrulestobindings method moved code applied rules call method provided method retrieves of bindings recursively.

here solution:

''' <summary>' ''' gets , returns list of bindings. ' ''' </summary>' ''' <returns>a list of known bindings.</returns>' private function getbindings() dictionary(of frameworkelement, list(of binding))     if _bindings nothing orelse _bindings.count = 0         _bindings = new dictionary(of frameworkelement, list(of binding))         findbindingsrecursively(me.parent, addressof retrievebindings)     end if     return _bindings end function   ''' <summary>' ''' recursively goes through control tree, looking bindings on current data context.' ''' </summary>' ''' <param name="element">the root element start searching at.</param>' ''' <param name="callbackdelegate">a delegate called when binding if found.</param>' private sub findbindingsrecursively(byval element dependencyobject, byval callbackdelegate foundbindingcallbackdelegate)      ' see if should display errors on element'     dim members memberinfo() = element.[gettype]().getmembers(bindingflags.[static] or bindingflags.[public] or bindingflags.flattenhierarchy)      each member memberinfo in members         dim dp dependencyproperty = nothing         ' check see if field or property given dependency property'         if member.membertype = membertypes.field             dim field fieldinfo = directcast(member, fieldinfo)             if gettype(dependencyproperty).isassignablefrom(field.fieldtype)                 dp = directcast(field.getvalue(element), dependencyproperty)             end if         elseif member.membertype = membertypes.[property]             dim prop propertyinfo = directcast(member, propertyinfo)             if gettype(dependencyproperty).isassignablefrom(prop.propertytype)                 dp = directcast(prop.getvalue(element, nothing), dependencyproperty)             end if          end if         if dp isnot nothing             ' have dependency property. '             'checking if has binding , if so, checking if bound property interested in'             dim bb binding = bindingoperations.getbinding(element, dp)             if bb isnot nothing                 ' element has dependencyproperty know of bound property interested in. '                 ' passing information call method caller can handle it.'                 if typeof element frameworkelement                     if me.datacontext isnot nothing andalso directcast(element, frameworkelement).datacontext isnot nothing                         callbackdelegate(directcast(element, frameworkelement), bb, dp)                     end if                 end if             end if         end if     next      'recursing through child elements'     if typeof element frameworkelement orelse typeof element frameworkcontentelement         each childelement object in logicaltreehelper.getchildren(element)             if typeof childelement dependencyobject                 findbindingsrecursively(directcast(childelement, dependencyobject), callbackdelegate)             end if         next     end if end sub  ''' <summary>' ''' called when recursively populating bindings dictionary frameworkelements(key) , corresponding list of bindings(value)' ''' </summary>' ''' <param name="element">the element binding belongs to</param>' ''' <param name="binding">the binding belongs element</param>' ''' <param name="dp">the dependencyproperty binding bound to</param>' ''' <remarks></remarks>' sub retrievebindings(byval element frameworkelement, byval binding binding, byval dp dependencyproperty)     'applying exception validation , data error validation rules binding'      'to ensure validation occurs element'     if binding.validationrules.tolist.find(function(x) gettype(exceptionvalidationrule) (x.gettype)) nothing         binding.validationrules.add(new exceptionvalidationrule())         binding.validationrules.add(new dataerrorvalidationrule())         binding.updatesourceexceptionfilter = new updatesourceexceptionfiltercallback(addressof returnexceptionhandler)         'resetting binding include validation rules added'         bindingoperations.setbinding(element, dp, binding)     end if      ' remember bound element. used display error messages each property.'     if _bindings.containskey(element)         directcast(_bindings(element), list(of binding)).add(binding)     else         _bindings.add(element, new list(of binding)({binding}))     end if end sub 

thanks!

-frinny

i'm not following how code works can't modify binding after has been used, can't add validationrules existing binding. think you'll have copy binding, property property , add validationrules , set new copied binding bindingoperations.setbinding(...).

another approach may create own subclassed binding add validationrules directly e.g

public class exbinding : binding {     public exbinding()     {         notifyonvalidationerror = true;         validationrules.add(new exceptionvalidationrule());         validationrules.add(new dataerrorvalidationrule());     } } 

useable like

<textbox text="{local:exbinding path=myproperty}"/> 

update

i don't think understood answer. can't modify binding once in use you're trying won't work. here's c# sample app shows this. contains 3 textboxs

  • first textbox adds binding exceptionvalidationrule in xaml
  • second textbox adds binding in xaml , adds exceptionvalidationrule in loaded event
  • third textbox adds binding exceptionvalidationrule in loaded event

the exceptionvalidationrule work textbox 1 , 3 not 2. uploaded sample here: http://www.mediafire.com/?venm09dy66q4rmq

update 2
work if set binding again after you've added validation rule like

bindingexpression bindingexpression = textbox.getbindingexpression(textbox.textproperty); binding textbinding = bindingexpression.parentbinding; textbinding.validationrules.add(new exceptionvalidationrule()); // set binding again after `exceptionvalidationrule` has been added bindingoperations.setbinding(textbox, textbox.textproperty, textbinding); 

i'm not sure how getbindings method look, maybe add setbindings method set bindings again , call method after you've added exceptionvalidationrules


Comments

Popular posts from this blog

apache - Add omitted ? to URLs -

redirect - bbPress Forum - rewrite to wwww.mysite prohibits login -

php - How can I stop spam on my custom forum/blog? -