wpf - Custom attached command -
i have situation want write custom command framework element. have done below:
public class undoredomanager { private static frameworkelement frameworkelement; /// <summary> /// undovmcommand attached properrty. /// </summary> public static readonly dependencyproperty undovmcommandproperty = dependencyproperty.registerattached("undovmcommand", typeof(icommand), typeof(undoredomanager), new frameworkpropertymetadata(undovmcommand, undovmcommand_propertychanged)); /// <summary> /// undovmcommandproperty getter. /// </summary> /// <param name="obj"></param> /// <returns></returns> [attachedpropertybrowsableforchildren] public static icommand getundovmcommand(dependencyobject obj) { return (icommand)obj.getvalue(undovmcommandproperty); } /// <summary> /// undovmcommandproperty setter. /// </summary> /// <param name="obj"></param> /// <param name="value"></param> public static void setundovmcommand(dependencyobject obj, icommand value) { obj.setvalue(undovmcommandproperty, value); } protected static void undovmcommand_propertychanged(dependencyobject obj, dependencypropertychangedeventargs e) { var control = obj frameworkelement; if (control != null) { if ((e.newvalue != null) && (e.oldvalue == null)) { frameworkelement = control; } else if ((e.newvalue == null) && (e.oldvalue != null)) { frameworkelement = null; } } } }
this attaching in xaml thus:
<itemscontrol x:name="graphcontrol" local:undoredomanager.undovmcommand="{binding undocommand}"> ...... </itemscontrol>
however, want fire command on button click.
<button content="undo" commandtarget="{binding elementname=graphcontrol}" command="thecommand" margin="5"/>
very
<button command="copy" commandtarget="{binding elementname=mytextbox1}">copy</button>
so have written following:
public static routeduicommand undovmcommand = new routeduicommand("thecommand", "thecommand", typeof(undoredomanager)); public static routeduicommand undovmcommand { { return undovmcommand; } } static undoredomanager() { commandmanager.registerclasscommandbinding(typeof(undoredomanager), new commandbinding(undovmcommand, executedeventhandler_undovm, canexecuteeventhandler_ifcanundovm)); } private static void canexecuteeventhandler_ifcanundovm(object sender, canexecuteroutedeventargs e) { frameworkelement frmele = sender frameworkelement; e.canexecute = false; if (null != frmele && frmele.datacontext viewmodelbase) { e.canexecute = true; //(frmele.datacontext graphviewmodel).canundo; } e.handled = true; } public static void executedeventhandler_undovm(object sender, executedroutedeventargs e) { frameworkelement frmele = sender frameworkelement; if (null != frmele && frmele.datacontext viewmodelbase) { (frmele.datacontext graphviewmodel).undocommand.execute(null); } }
i not getting how wire that. should declare above routed command? cannot in frameworkelement class. there way attach that? sorry, if havent been able state problem clearly. put in short simple way: if write "copy" command textbox in attached manner, how can that?
edit: after @erti's comment:
now have 2 classes, undoredomanager
public class undoredomanager { private static frameworkelement frameworkelement; /// <summary> /// undovmcommand attached properrty. /// </summary> public static readonly dependencyproperty undovmcommandproperty = dependencyproperty.registerattached("undovmcommand", typeof(icommand), typeof(undoredomanager), new frameworkpropertymetadata(staticcommand.undovmcommand, undovmcommand_propertychanged)); /// <summary> /// undovmcommandproperty getter. /// </summary> /// <param name="obj"></param> /// <returns></returns> [attachedpropertybrowsableforchildren] public static icommand getundovmcommand(dependencyobject obj) { return (icommand)obj.getvalue(undovmcommandproperty); } /// <summary> /// undovmcommandproperty setter. /// </summary> /// <param name="obj"></param> /// <param name="value"></param> public static void setundovmcommand(dependencyobject obj, icommand value) { obj.setvalue(undovmcommandproperty, value); } protected static void undovmcommand_propertychanged(dependencyobject obj, dependencypropertychangedeventargs e) { var control = obj frameworkelement; if (control != null) { if ((e.newvalue != null) && (e.oldvalue == null)) { frameworkelement = control; } else if ((e.newvalue == null) && (e.oldvalue != null)) { frameworkelement = null; } } } }
please note default value passed in propertymetadata while registering dependency property. in xaml using as:
<itemscontrol x:name="graphcontrol" local:undoredomanager.undovmcommand="{binding undocommand}"/>
another staticcommand class:
public class staticcommand { public static routeduicommand undovmcommand = new routeduicommand("thecommand", "thecommand", typeof(undoredomanager)); public static routeduicommand undovmcommand { { return undovmcommand; } } static staticcommand() { commandmanager.registerclasscommandbinding(typeof(staticcommand), new commandbinding(undovmcommand, executedeventhandler_undovm, canexecuteeventhandler_ifcanundovm)); } private static void canexecuteeventhandler_ifcanundovm(object sender, canexecuteroutedeventargs e) { //this not getting hit. e.canexecute = true; e.handled = true; } public static void executedeventhandler_undovm(object sender, executedroutedeventargs e) { //i here } }
in xaml using as:
<button content="undo" commandtarget="{binding elementname=graphcontrol}" command="{binding source={x:static local:staticcommand.undovmcommand}}" margin="5"/>
but above button not getting activated @ all.
you have it. create new class staticcommands.cs.
all have is, bind against static command, such:
<button command="{x:static local:staticcommands.undovmcommand}" commandtarget="{binding whatever want}" />
now in executedeventhandler_undovm, have access button element, means can access commandtarget property, if needed.
check out too: wpf commands, how declare application level commands?
Comments
Post a Comment