c# - How to specify a DataContext whet adding the ContextMenu to the DataGridTemplateColumn? -
i cooking datagridtemplatecolumns programmatically via
datatemplate dtstringtemplate = (datatemplate)xamlreader.load(sr, pc); datagridtemplatecolumn.celltemplate = dtstringtemplate;
i tried adding contextmenu datagrid, editable cells used own context menu.
so far, post has gotten me far getting textbox context menu appear expected: how add contextmenu in wpf datagridcolumn in mvvm?
using post mentioned above guide, have created style , contextmenu in app.xaml; when right-click on cell in datagrid, context menu appears. however, can't associated command fire, , suspect binding not right. here's xaml in app.xaml:
<contextmenu x:key="datagridcontextmenu"> <menuitem header="menuitem one" command="{binding relativesource={relativesource findancestor, ancestortype={x:type datagrid}}, path=datacontext.cmdmenuitemone}" /> <menuitem header="menuitem two" command="{binding relativesource={relativesource findancestor, ancestortype={x:type datagrid}}, path=datacontext.cmdmenuitemone}" /> </contextmenu>
the datacontext datagrid myviewmodel; myviewmodel has public delegatecommand named cmdmenuitemone.
unfortunately, cmdmenuitemone never called.
misunderstanding in binding? ...
since fact contextmenu isn't part of datagrid's visual tree, cannot access property defined in datagrid's datacontext. can next workaround that.
- create boolean attached property define next thing; if value of added property true, find visual parent of object property attached to, , assign parent's datacontext tag property of object property attached to, other hand if value of attached property false , tag property assign null.
- create extension helper method scan visual tree of caller , return it's(caller) parent of specific type.
- create default style datagridcell object use dependency property described above , define contextmenu. set style resource in app.xaml(take in account style used datagridcell objects in project).
style code (should in app.xaml)
<style targettype="datagridcell"> <setter property="datagridcreatecolumnandbinditefromcodebehind:datagridattached.setdatagriddatacontexttotag" value="true"></setter> <setter property="contextmenu"> <setter.value> <contextmenu datacontext="{binding path=placementtarget.tag, relativesource={relativesource self}}"> <menuitem header="menuitem one" command="{binding cmdmenuitemone}" /> <menuitem header="menuitem two" command="{binding cmdmenuitemtwo}" /> </contextmenu> </setter.value> </setter></style>
attached property code
public class datagridattached { public static readonly dependencyproperty setdatagriddatacontexttotagproperty = dependencyproperty.registerattached( "setdatagriddatacontexttotag", typeof (bool), typeof (datagridattached), new propertymetadata(default(bool), setparentdatacontexttotagpropertychangedcallback)); public static void setsetdatagriddatacontexttotag(dependencyobject element, bool value) { element.setvalue(setdatagriddatacontexttotagproperty, value); } public static bool getsetdatagriddatacontexttotag(dependencyobject element) { return (bool) element.getvalue(setdatagriddatacontexttotagproperty); } private static void setparentdatacontexttotagpropertychangedcallback(dependencyobject dependencyobject, dependencypropertychangedeventargs args) { performdatacontexttotagassignment(dependencyobject frameworkelement, (bool)args.newvalue); } private static void performdatacontexttotagassignment(frameworkelement sender, bool isattaching) { var control = sender; if (control == null) return; if (isattaching == false) { control.tag = null; } else { var datagrid = control.findparent<datagrid>(); if (datagrid == null) return; control.tag = datagrid.datacontext; } } }
helper code
public static class visualtreehelperextensions { public static t findparent<t>(this dependencyobject child) t : dependencyobject { while (true) { //get parent item dependencyobject parentobject = visualtreehelper.getparent(child); //we've reached end of tree if (parentobject == null) return null; //check if parent matches type we're looking t parent = parentobject t; if (parent != null) return parent; child = parentobject; } } }
regards.
Comments
Post a Comment