.net - WPF validation adorners - only show if the control has held focus before -


in wpf application, want show validation adorner after control has been edited/entered/focused user. way user given chance provide valid input field , if chose not to, validation display.

we want encourage every field completed indicating mandatory fields when form first opens may circumvent user inclined complete need in order rid of big red validation errors may circumvent flow of form.

is there way know if control has held focus yet? attached property maybe work?

in case helps provide more concrete response: here current validation style displays red border [if control has border] , little exclamation mark tooltip error message (pretty standard really):

<style targettype="control">     <style.triggers>         <trigger property="validation.haserror" value="true">             <setter property="tooltip"                     value="{binding relativesource={x:static relativesource.self},                     path=(validation.errors).currentitem.errorcontent}"/>              <setter property="validation.errortemplate">                 <setter.value>                     <controltemplate>                         <dockpanel lastchildfill="true">                             <image source="../resources/icons/error.ico" margin="4" width="15" tooltip="{binding elementname=customadorner, path=adornedelement.(validation.errors).currentitem.errorcontent}" />                             <adornedelementplaceholder name="customadorner" verticalalignment="center" >                                 <border borderbrush="red" borderthickness="1" visibility="{binding elementname=customadorner, path=adornedelement.borderthickness, converter={staticresource hasbordertovisibilityconverter}}" />                             </adornedelementplaceholder>                         </dockpanel>                     </controltemplate>                 </setter.value>             </setter>         </trigger>         <trigger property="isvisible" value="false">             <setter property="validation.errortemplate" value="{x:null}"/>         </trigger>     </style.triggers> </style> 

you combine attached behavior attached property this. attached behavior, observefocus subscribe gotfocus event , in event handler set hasheldfocus attached property true

it used set property in viewmodel this

<button local:hasheldfocusbehavior.observefocus="true"         local:hasheldfocusbehavior.hasheldfocus="{binding hasheldfocus,                                                            mode=onewaytosource}"/> 

here example of how used change background of button once has been focused

<style targettype="button">     <setter property="background" value="red"/>     <setter property="local:hasheldfocusbehavior.observefocus" value="true"/>     <style.triggers>         <datatrigger binding="{binding relativesource={relativesource self},                                        path=(local:hasheldfocusbehavior.hasheldfocus)}"                         value="true">             <setter property="background" value="green"/>         </datatrigger>     </style.triggers> </style> 

hasheldfocusbehavior

public static class hasheldfocusbehavior {     public static readonly dependencyproperty observefocusproperty =         dependencyproperty.registerattached("observefocus",                                             typeof(bool),                                             typeof(hasheldfocusbehavior),                                             new uipropertymetadata(false, onobservefocuschanged));     public static bool getobservefocus(dependencyobject obj)     {         return (bool)obj.getvalue(observefocusproperty);     }     public static void setobservefocus(dependencyobject obj, bool value)     {         obj.setvalue(observefocusproperty, value);     }     private static void onobservefocuschanged(dependencyobject dpo,                                               dependencypropertychangedeventargs e)     {         uielement element = dpo uielement;         element.focus();         if ((bool)e.newvalue == true)         {             sethasheldfocus(element, element.isfocused);             element.gotfocus += element_gotfocus;         }         else         {             element.gotfocus -= element_gotfocus;         }     }     static void element_gotfocus(object sender, routedeventargs e)     {         uielement element = sender uielement;         sethasheldfocus(element, true);     }      private static readonly dependencyproperty hasheldfocusproperty =         dependencyproperty.registerattached("hasheldfocus",                                             typeof(bool),                                             typeof(hasheldfocusbehavior),                                             new uipropertymetadata(false));     public static void sethasheldfocus(dependencyobject element, bool value)     {         element.setvalue(hasheldfocusproperty, value);     }     public static bool gethasheldfocus(dependencyobject element)     {         return (bool)element.getvalue(hasheldfocusproperty);     } } 

update

in case, replace validation.haserror trigger multitrigger

<style targettype="control">     <style.triggers>         <multidatatrigger>             <multidatatrigger.conditions>                 <condition binding="{binding relativesource={relativesource self},                                              path=(validation.haserror)}"                            value="true"/>                 <condition binding="{binding relativesource={relativesource self},                                              path=(local:hasheldfocusbehavior.hasheldfocus)}"                            value="true"/>             </multidatatrigger.conditions>             <!-- setters.. -->         </multidatatrigger>         <!-- ... -->     </style.triggers> </style> 

Comments

Popular posts from this blog

linux - Mailx and Gmail nss config dir -

c# - Is it possible to remove an existing registration from Autofac container builder? -

php - Mysql PK and FK char(36) vs int(10) -