c# - WPF Event Handler in Another Class -
i have built series of event handlers custom wpf controls. event handles format text displayed when user enters or leaves textbox based on type of data contained (phone number, zip code, monetary value, etc.)
right have of events locally in c# code directly attached xaml. because have developed controls, means logic repeated lot, , if want change program-wide functionality have make changes everywhere event code located.
i sure there way put of event handlers in single class. can point me in correct direction?
i saw article: event handler located in different class mainwindow i'm not sure if directly relates i'm doing. rather make small changes existing logic have, works, rewrite commands.
i if possible:
lostfocus="expandedtextboxevents.textbox_lostfocus" it easy enough this:
private void textboxcurrencygotfocus(object sender, routedeventargs e) { expandedtextboxevents.textboxcurrencygotfocus(sender, e); } private void textboxcurrencylostfocus(object sender, routedeventargs e) { expandedtextboxevents.textboxcurrencylostfocus(sender, e); } but less elegant.
attached properties 1 approach want. use them often.
attached property code:
public class textboxformatter ' ------------------------------------------------------ ' define formattype attached property public shared readonly formattypeproperty dependencyproperty = _ dependencyproperty.registerattached( _ name:="formattype", _ propertytype:=gettype(textboxformattertype), _ ownertype:=gettype(textboxformatter), _ defaultmetadata:=new frameworkpropertymetadata( _ defaultvalue:=textboxformattertype.none, _ propertychangedcallback:=new propertychangedcallback(addressof formattypepropertychanged) _ ) _ ) ' ------------------------------------------------------ ' define "getter" , "setter" formattype public shared function getformattype(byval target dependencyobject) textboxformattertype target.getvalue(formattypeproperty) end function public shared sub setformattype(byval target dependencyobject, byval value textboxformattertype) target.setvalue(formattypeproperty, value) end sub ' ------------------------------------------------------ ' define formattype "propertychanged" event handler private shared sub formattypepropertychanged(byval target dependencyobject, byval e dependencypropertychangedeventargs) if ctype(e.newvalue, textboxformattertype) = textboxformattertype.none unregisterformattypecontrol(target) else registerformattypecontrol(target) end if end sub ' ------------------------------------------------------ ' define collection of event listerns ' formattype "propertychanged" event private shared _registeredformattypecontroldelegates new dictionary(of textbox, routedeventhandler) ' ------------------------------------------------------ ' register control event listener ' (also, attach control's lostfocus event) private shared sub registerformattypecontrol(byval candidate dependencyobject) dim l_control = trycast(candidate, textbox) if l_control isnot nothing dim l_handler = new routedeventhandler(addressof formattypecontrol_lostfocus) _registeredformattypecontroldelegates.add(l_control, l_handler) l_control.addhandler(textbox.lostfocusevent, l_handler) end if end sub ' ------------------------------------------------------ ' unregister control event listener ' (also, unattach control's lostfocus event) private shared sub unregisterformattypecontrol(byval candidate dependencyobject) dim l_control = trycast(candidate, textbox) if l_control isnot nothing andalso _registeredformattypecontroldelegates.containskey(l_control) dim l_handler = _registeredformattypecontroldelegates(l_control) l_control.removehandler(textbox.lostfocusevent, l_handler) _registeredformattypecontroldelegates.remove(l_control) end if end sub ' ------------------------------------------------------ ' on control's lostfocus event, apply format ' (you apply format based on event, ' careful if using textchanged event - ' fire whether user has changed text or ' code has changed text - introduce ' infinite loop) private shared sub formattypecontrol_lostfocus(byval sender object, byval e routedeventargs) dim l_textbox = trycast(e.source, textbox) if l_textbox isnot nothing dim l_formattype = ctype(l_textbox.getvalue(formattypeproperty), textboxformattertype) select case l_formattype case textboxformattertype.socialsecuritynumber ' apply format l_textbox ' (what want social security number like?) case textboxformattertype.zipcode ' apply format l_textbox ' (what want zip code like?) case textboxformattertype.etc ' apply format l_textbox end select end if end sub end class public enum textboxformattertype none zipcode socialsecuritynumber etc end enum the above looks bit cluttered, once code written (once), can use on , on again in ui:
<window x:class="window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:this="clr-namespace:wpfapplication1" title="window1"> <grid> <stackpanel> <textbox this:textboxformatter.formattype="socialsecuritynumber" /> <textbox this:textboxformatter.formattype="zipcode" /> <textbox this:textboxformatter.formattype="none" /> </stackpanel> </grid> </window> one advantage approach "formattype" becomes dependency property, meaning can bind values @ run-time (rather harcoding, in example above). example:
<textbox this:textboxformatter.formattype="{binding viewmodel.desiredformat}" />
Comments
Post a Comment